{"id":105503,"date":"2025-02-27T20:13:41","date_gmt":"2025-02-27T20:13:41","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=105503"},"modified":"2025-02-06T20:23:10","modified_gmt":"2025-02-06T20:23:10","slug":"mysql-shell-basic-configuration-management-part-3-disk-i-o-and-storage-optimization","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/mysql\/mysql-shell-basic-configuration-management-part-3-disk-i-o-and-storage-optimization\/","title":{"rendered":"MySQL Shell Basic Configuration Management (Part 3 \u2013 Disk I\/O and Storage Optimization)"},"content":{"rendered":"<p>This is part of a series of posts from Chisom Kanu about using MySQL Shell in the management of MySQL. You can see the <a href=\"https:\/\/www.red-gate.com\/simple-talk\/collections\/chisom-kanus-series-mysql-shell-and-basic-configuration-management\/\">entire series here<\/a>.<\/p>\n\n<p>So far, in our previous articles on MySQL optimization, we&#8217;ve looked at <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/mysql\/part-i-introduction-to-mysql-shell-and-basic-configuration-management\/\">basic configuration management<\/a> and <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/mysql\/memory-and-cpu-configuration-using-mysql-shell\/\">memory and CPU<\/a> tuning using MySQL Shell. In the first article, we looked into how to optimize your MySQL database\u2019s configuration with MySQL Shell. In the second article, we focused on memory and CPU usage, showing how to monitor and improve performance by adjusting important settings. In this third installment in the series, we&#8217;ll continue our series by going into another important aspect of database optimization\u2014<a href=\"https:\/\/scoutapm.com\/blog\/understanding-disk-i-o-when-should-you-be-worried#:~:text=Disk%20I%2FO%20encompasses%20the,the%20same%20goes%20for%20writing).\">disk I\/O<\/a> and storage.<\/p>\n<p>Disk I\/O plays an important role in how fast MySQL can read and write data. Even if your memory and CPU are optimized, poor disk I\/O performance can cause issues in the entire system. This is especially important for write-heavy databases or those handling large datasets, as the speed of disk operations can dramatically affect overall performance. <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.4\/en\/innodb-introduction.html\">InnoDB<\/a>, the default storage engine in MySQL, is highly reliant on efficient disk I\/O. By tweaking its settings, you can reduce latency and improve throughput. We will cover the essential MySQL Shell commands and scripts to monitor, configure, and optimize your disk I\/O and storage for maximum performance.<\/p>\n<p>We begin by accessing MySQL Shell. If you\u2019ve been following along in this series, you\u2019re likely familiar with how to do this. But just to make sure we\u2019re on the same page, here\u2019s how to get started. Open your terminal and type:<\/p>\n<pre class=\"lang:none theme:none\">mysqlsh --uri root@localhost<\/pre>\n<p>If you need to enter a password, you&#8217;ll be prompted.. If you&#8217;re unsure about connection details, please refer back to <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/mysql\/part-i-introduction-to-mysql-shell-and-basic-configuration-management\/\">Part 1 of this series<\/a>.<\/p>\n<p><em>Note that this will connect with the very powerful root user, so be careful doing this on a production server if you are not sure what you are doing.<\/em><\/p>\n<p>After connecting, switch to JavaScript mode (since we\u2019ll be using JavaScript commands in MySQL Shell) by typing <code>\\js<\/code>. Now, we\u2019re ready to work with disk I\/O settings.<\/p>\n<h2><a id=\"post-105503-_heading=h.qiu8ftp4p2dx\"><\/a>Why We&#8217;re Using MySQL Shell<\/h2>\n<p>Now, you might be wondering, &#8220;Can&#8217;t we just run SQL commands to do most of what is in this article?&#8221; And you&#8217;re right, in many cases we could. But MySQL Shell offers several advantages that make our optimization journey smoother:<\/p>\n<ul>\n<li><strong>Reusability<\/strong>: We can create functions that package complex operations into easy-to-use commands.<\/li>\n<li><strong>Scripting<\/strong>: We can combine multiple operations and add logic, making our optimizations smarter.<\/li>\n<li><strong>Consistency<\/strong>: By saving our functions, we ensure we&#8217;re always running optimizations the same way.<\/li>\n<li><strong>Automation<\/strong>: We can easily schedule and run complex monitoring and optimization tasks.<\/li>\n<\/ul>\n<p>It allows us to build tools around basic SQL commands, making our optimization process more efficient and less error prone.<\/p>\n<h2><a id=\"post-105503-_heading=h.gjdgxs\"><\/a>Configuring InnoDB I\/O Settings with MySQL Shell<\/h2>\n<p>The most important settings for controlling disk I\/O in MySQL\u2019s InnoDB engine are innodb_io_capacity and innodb_io_capacity_max. These parameters dictate the maximum number of I\/O operations InnoDB will perform per second. Configuring these appropriately for your hardware is crucial. For instance, if you\u2019re using fast SSD storage, you can set a higher value, allowing InnoDB to perform more operations per second.<\/p>\n<p>Let\u2019s first check the current settings by running the following script in MySQL Shell:<\/p>\n<pre class=\"lang:none theme:none\">var result = \n   session.runSql('SHOW VARIABLES LIKE \"innodb_io_capacity\"');\nvar row;\nwhile (row = result.fetchOne()) {\n    print(row[0] + \": \" + row[1]);\n}<\/pre>\n<p>When you run this script, you\u2019ll get the current configuration for both <code>innodb_io_capacity<\/code> and <code>innodb_io_capacity_max<\/code>. For example, you might see output like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"573\" height=\"34\" class=\"wp-image-105507\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/02\/word-image-105503-1-1.png\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/02\/word-image-105503-1-1.png 573w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/02\/word-image-105503-1-1-300x18.png 300w\" sizes=\"auto, (max-width: 573px) 100vw, 573px\" \/><\/p>\n<p>This tells us that InnoDB is currently set to handle up to 10000 I\/O operations per second and can go as high as 20000 if necessary. If you have faster hardware, like an SSD that can handle a higher I\/O load, you\u2019ll likely want to increase these values.<\/p>\n<p>To adjust them, we can run the following commands:<\/p>\n<pre class=\"lang:none theme:none\">session.runSql('SET GLOBAL innodb_io_capacity = 20000');\nsession.runSql('SET GLOBAL innodb_io_capacity_max = 40000');\nprint(\"InnoDB I\/O capacity settings updated.\");<\/pre>\n<p>After changes these settings higher, InnoDB will be able to handle more read and write operations per second, which can improve performance, especially for databases with high I\/O demand.<\/p>\n<h3><a id=\"post-105503-_heading=h.3wlsy3s0pv2r\"><\/a>Monitoring Disk I\/O Performance<\/h3>\n<p>After adjusting the I\/O capacity, we want to monitor whether the system is effectively using the available I\/O resources. Let&#8217;s create a more comprehensive script to check InnoDB&#8217;s disk I\/O performance:<\/p>\n<pre class=\"lang:none theme:none \">function checkDiskIOPerformance() {\n    var metrics = [\n        \"Innodb_data_reads\",\n        \"Innodb_data_writes\",\n        \"Innodb_data_fsyncs\",\n        \"Innodb_data_pending_reads\",\n        \"Innodb_data_pending_writes\",\n        \"Innodb_data_pending_fsyncs\"\n    ];\n    \n    var values = {};\n    for (var i = 0; i &lt; metrics.length; i++) {\n        var result = session.runSql('SHOW GLOBAL STATUS LIKE \"' + metrics[i] + '\"');\n        values[metrics[i]] = parseInt(result.fetchOne()[1]);\n    }\n    \n    print(\"InnoDB Disk I\/O Performance:\");\n    print(\"Data reads: \" + values.Innodb_data_reads);\n    print(\"Data writes: \" + values.Innodb_data_writes);\n    print(\"Data fsyncs: \" + values.Innodb_data_fsyncs);\n    print(\"Pending reads: \" + values.Innodb_data_pending_reads);\n    print(\"Pending writes: \" + values.Innodb_data_pending_writes);\n    print(\"Pending fsyncs: \" + values.Innodb_data_pending_fsyncs);\n    \n    var readRatio = values.Innodb_data_pending_reads \/ values.Innodb_data_reads;\n    var writeRatio = values.Innodb_data_pending_writes \/ values.Innodb_data_writes;\n    \n    print(\"\\nDisk Pressure Analysis:\");\n    print(\"Read pressure: \" + (readRatio * 100).toFixed(2) + \"%\");\n    print(\"Write pressure: \" + (writeRatio * 100).toFixed(2) + \"%\");\n    \n    if (readRatio &gt; 0.1 || writeRatio &gt; 0.1) {\n        print(\"\\nWARNING: Your I\/O subsystem may be under pressure.\");\n        print(\"Consider increasing innodb_io_capacity or upgrading your storage.\");\n    } else {\n        print(\"\\nYour I\/O subsystem appears to be handling the load well.\");\n    }\n};\nmodule.exports.checkDiskIOPerformance = checkDiskIOPerformance;\n<\/pre>\n<p>\u00a0<\/p>\n<p>Here, we&#8217;re collecting six key metrics related to InnoDB&#8217;s disk operations. The script calculates &#8220;pressure ratios&#8221; for both reads and writes; these ratios represent the proportion of pending operations to total operations. We interpret these ratios as percentages to give a clearer picture of disk pressure.<\/p>\n<p>When you run the <code>`checkDiskIOPerformance()`<\/code> function, the first six lines show the raw numbers of operations performed and pending. The &#8220;pressure&#8221; percentages give you a quick way to gauge system performance:<\/p>\n<ul>\n<li>If these percentages are below 10% (0.1), your system is likely handling I\/O well.<\/li>\n<li>If they exceed 10%, it might indicate that your storage is struggling to keep up with demand.<\/li>\n<li>The script provides an interpretation based on these percentages.<\/li>\n<\/ul>\n<p>Remember, these numbers have been accumulating since the server started. To get a more accurate picture of current performance, you should run this function at regular intervals (e.g., every hour). Compare the differences between runs to see how many operations occurred in that time period and also look for trends over time. Are the pressure percentages increasing?<\/p>\n<p>By monitoring these metrics regularly, you can identify when your system is approaching its I\/O limits, make informed decisions about when to increase `innodb_io_capacity` or upgrade your storage, also correlate I\/O performance with other system changes or increased load.<\/p>\n<h2><a id=\"post-105503-_heading=h.1fob9te\"><\/a>Optimizing Data and Log File Storage with MySQL Shell<\/h2>\n<p>In addition to adjusting I\/O capacity, it\u2019s essential to look at how MySQL manages its data and log files. The size and location of these files can have a significant impact on performance.<\/p>\n<p>To see the current location of the data file, use the following commands:<\/p>\n<pre class=\"lang:none theme:none\">var result = session.runSql('SHOW VARIABLES LIKE \"innodb_data_file_path\"');\n\nprint(\"Data file path: \" + result.fetchOne()[1]);<\/pre>\n<p>This will return something like:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"560\" height=\"45\" class=\"wp-image-105508\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/02\/word-image-105503-2-1.png\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/02\/word-image-105503-2-1.png 560w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2025\/02\/word-image-105503-2-1-300x24.png 300w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/p>\n<p>This will tell you where MySQL is storing the InnoDB data file. If the file is located on a slow disk, moving it to faster storage, such as an SSD, can help.<\/p>\n<p>We can also check the size of the log file, which plays an important role in how quickly MySQL can write changes to disk:<\/p>\n<pre class=\"lang:none theme:none\">result = session.runSql('SHOW VARIABLES LIKE \"innodb_log_file_size\"');\n\nprint(\"Log file size: \" + result.fetchOne()[1] + \" bytes\");<\/pre>\n<p>A larger log file can improve performance by reducing the frequency of flushes to disk, especially for write-heavy workloads. If your database has grown or you\u2019ve increased your innodb_io_capacity, increasing the log file size might be a good next step.<\/p>\n<h2><a id=\"post-105503-_heading=h.3znysh7\"><\/a>Fine-Tuning InnoDB Log Files with MySQL Shell<\/h2>\n<p>The number of InnoDB log files can significantly impact performance, especially for databases with frequent write operations. Let&#8217;s create a function that not only checks the current configuration but also provides guidance on potential adjustments:<\/p>\n<pre class=\"lang:none theme:none\">function analyzeInnoDBLogFiles() {\n    var logFilesResult = session.runSql('SHOW VARIABLES LIKE \"innodb_log_files_in_group\"');\n    var logFileSize = session.runSql('SHOW VARIABLES LIKE \"innodb_log_file_size\"');\n    var bufferPoolSize = session.runSql('SHOW VARIABLES LIKE \"innodb_buffer_pool_size\"');\n    var numLogFiles = parseInt(logFilesResult.fetchOne()[1]);\n    var logSize = parseInt(logFileSize.fetchOne()[1]);\n    var bufferSize = parseInt(bufferPoolSize.fetchOne()[1]);\n    print(\"Current InnoDB Log File Configuration:\");\n    print(\"Number of log files: \" + numLogFiles);\n    print(\"Size of each log file: \" + (logSize \/ (1024 * 1024)).toFixed(2) + \" MB\");\n    print(\"Total log file size: \" + (numLogFiles * logSize \/ (1024 * 1024)).toFixed(2) + \" MB\");\n    print(\"InnoDB buffer pool size: \" + (bufferSize \/ (1024 * 1024)).toFixed(2) + \" MB\");\n    var totalLogSize = numLogFiles * logSize;\n    var recommendedLogSize = Math.min(bufferSize \/ 4, 4 * 1024 * 1024 * 1024);  \/\/ 25% of buffer pool, max 4GB\n    print(\"\\nAnalysis:\");\n    if (totalLogSize &lt; recommendedLogSize) {\n        print(\"Your total log file size might be too small. Consider increasing it.\");\n        print(\"Recommended total log size: \" + (recommendedLogSize \/ (1024 * 1024)).toFixed(2) + \" MB\");\n        print(\"You can achieve this by either:\");\n        print(\"1. Increasing the number of log files, or\");\n        print(\"2. Increasing the size of each log file\");\n    } else if (totalLogSize &gt; recommendedLogSize * 1.5) {\n        print(\"Your total log file size might be larger than necessary.\");\n        print(\"Consider reducing it to save disk space and potentially improve performance.\");\n    } else {\n        print(\"Your current log file configuration seems appropriate.\");\n    }\n    print(\"\\nTo make changes, add or modify these lines in your MySQL configuration file:\");\n    print(\"innodb_log_files_in_group = \" + numLogFiles);\n    print(\"innodb_log_file_size = \" + logSize);\n    print(\"\\nThen restart MySQL for changes to take effect.\");\n    print(\"\\nRemember: Changing log file size requires MySQL to rebuild the log files, which can take time.\");\n}\nmodule.exports.analyzeInnoDBLogFiles = analyzeInnoDBLogFiles;<\/pre>\n<p>This function retrieves the current settings for the number of log files, size of each log file, and the InnoDB buffer pool size, it calculates the total log file size and compares it to a recommended size (25% of the buffer pool size, up to a maximum of 4GB) and based on this comparison, it provides specific recommendations.<\/p>\n<p>When you run <code>`analyzeInnoDBLogFiles()`<\/code>, the first section shows your current configuration, giving you a clear picture of your log file setup. The analysis section provides a recommendation based on best practices: If your total log size is less than 25% of your buffer pool (up to 4GB), it suggests increasing it. If it&#8217;s significantly larger, it suggests you might be able to reduce it, and if it&#8217;s within a reasonable range, it confirms your configuration is appropriate. It provides the exact lines you&#8217;d need to add or modify in your MySQL configuration file to implement any changes. This approach is more flexible and informative:<\/p>\n<ul>\n<li>It doesn&#8217;t assume a one-size-fits-all solution.<\/li>\n<li>It bases recommendations on your current buffer pool size, which is a key factor in determining optimal log file size.<\/li>\n<li>It explains the reasoning behind the recommendations, helping you make an informed decision.<\/li>\n<\/ul>\n<p>Also, while this function provides guidance, the optimal configuration can vary based on your specific workload and hardware. Always test changes in a non-production environment first and monitor performance before and after any modifications.<\/p>\n<h2><a id=\"post-105503-_heading=h.tyjcwt\"><\/a>Optimizing Tables for Better Disk Performance<\/h2>\n<p>In addition to tuning settings, periodically optimizing your tables can improve disk I\/O performance by reducing fragmentation and reclaiming unused space. Here\u2019s a script to optimize all tables in a given database:<\/p>\n<pre class=\"lang:none theme:none\">function optimizeTables(database) {\n    var tables = session.runSql('SHOW TABLES IN ' + database).fetchAll();\n    print(\"Found \" + tables.length + \" tables in database '\" + database + \"'\");\n    print(\"Starting optimization process...\");\n    \n    for (var i = 0; i &lt; tables.length; i++) {\n        var tableName = tables[i][0];\n        print(\"Optimizing table \" + (i + 1) + \" of \" + tables.length + \": \" + database + \".\" + tableName);\n        var result = session.runSql('OPTIMIZE TABLE ' + database + '.' + tableName);\n        var status = result.fetchOne()[3];  \/\/ The status message\n        print(\"Status: \" + status);\n    }\n    \n    print(\"Table optimization complete for database '\" + database + \"'\");\n}\nmodule.exports.optimizeTables = optimizeTables;<\/pre>\n<p>The function takes a <code>`database`<\/code> parameter, which is the name of the database you want to optimize.<\/p>\n<p>It first retrieves a list of all tables in the specified database, for each table, it runs the <code>`OPTIMIZE TABLE`<\/code> statement and reports the status and it provides progress updates, showing which table is being optimized and how many are left.<\/p>\n<p>To use this function, you would call it like this:<\/p>\n<pre class=\"lang:none theme:none\">optimizeTables('your_database_name');<\/pre>\n<p>Replace <code>'your_database_name'<\/code> with the actual name of your database. When you run this function, you&#8217;ll see the total number of tables in your database, the progress of the optimization process, showing which table is currently being optimized, and the status of each optimization operation. &#8220;OK&#8221; means the table was successfully optimized, while &#8220;Table is already up to date&#8221; means no optimization was necessary.<\/p>\n<p>It&#8217;s important to note a few things about table optimization:<\/p>\n<ul>\n<li>The <code>`OPTIMIZE TABLE`<\/code> command can be resource-intensive, especially for large tables. It&#8217;s best to run this during off-peak hours.<\/li>\n<li>For InnoDB tables, this command is essentially equivalent to recreating the table, which can take a while for large tables.<\/li>\n<li>Regular optimization is most beneficial for tables that experience frequent deletions or updates.<\/li>\n<\/ul>\n<h2><a id=\"post-105503-_heading=h.7arbxc98clw6\"><\/a>Long-Term Performance Tracking<\/h2>\n<p>You know how we&#8217;ve been looking at all these performance metrics? Well, it&#8217;s great to check them now and then, but wouldn&#8217;t it be even better if we could see how they change over time? That&#8217;s where long-term performance tracking comes in. Let&#8217;s set up a system to capture these stats regularly and store them in a table. This way, we can spot trends and catch potential issues before they become real problems.<\/p>\n<p>First, let&#8217;s create a table to store our performance metrics:<\/p>\n<pre class=\"lang:none theme:none\">function setupPerformanceTracking() {\n    session.runSql(`\n        CREATE TABLE IF NOT EXISTS performance_metrics (\n            id INT AUTO_INCREMENT PRIMARY KEY,\n            timestamp DATETIME,\n            innodb_data_reads BIGINT,\n            innodb_data_writes BIGINT,\n            innodb_data_fsyncs BIGINT,\n            innodb_data_pending_reads INT,\n            innodb_data_pending_writes INT,\n            innodb_data_pending_fsyncs INT\n        )\n    `);\n    print(\"Performance tracking table created. You're all set to start collecting data!\");\n}\nmodule.exports.setupPerformanceTracking = setupPerformanceTracking;<\/pre>\n<p>Run this function once to set up your tracking table.<\/p>\n<p>Now, let&#8217;s create a function to capture these metrics regularly:<\/p>\n<pre class=\"lang:none theme:none\">function trackPerformance() {\n    var metrics = [\n        \"Innodb_data_reads\",\n        \"Innodb_data_writes\",\n        \"Innodb_data_fsyncs\",\n        \"Innodb_data_pending_reads\",\n        \"Innodb_data_pending_writes\",\n        \"Innodb_data_pending_fsyncs\"\n    ];\n    \n    var values = [];\n    for (var i = 0; i &lt; metrics.length; i++) {\n        var result = session.runSql('SHOW GLOBAL STATUS LIKE \"' + metrics[i] + '\"');\n        values.push(parseInt(result.fetchOne()[1]));\n    }\n    \n    session.runSql(`\n        INSERT INTO performance_metrics \n        (timestamp, innodb_data_reads, innodb_data_writes, innodb_data_fsyncs,\n         innodb_data_pending_reads, innodb_data_pending_writes, innodb_data_pending_fsyncs)\n        VALUES (NOW(), ?, ?, ?, ?, ?, ?)\n    `, values);\n    \n    print(\"Performance metrics recorded. Keep it up!\");\n}\nmodule.exports.trackPerformance = trackPerformance;<\/pre>\n<p>You&#8217;ll want to run this regularly &#8211; maybe every hour or so. You could schedule a task to call this function automatically using whatever tools you have in the OS you are using.<\/p>\n<p>Finally, let&#8217;s create a function to analyze these trends:<\/p>\n<pre class=\"lang:none theme:none\">function analyzePerformanceTrends() {\n    var result = session.runSql(`\n        SELECT \n            DATE(timestamp) as date,\n            AVG(innodb_data_reads) as avg_reads,\n            AVG(innodb_data_writes) as avg_writes,\n            AVG(innodb_data_pending_reads) \/ AVG(innodb_data_reads) as avg_read_pressure,\n            AVG(innodb_data_pending_writes) \/ AVG(innodb_data_writes) as avg_write_pressure\n        FROM performance_metrics\n        GROUP BY DATE(timestamp)\n        ORDER BY DATE(timestamp) DESC\n        LIMIT 7\n    `);\n    regularly\u2014maybe\n    print(\"Performance Trends (Last 7 Days):\");\n    print(\"Date\\t\\tAvg Reads\\tAvg Writes\\tRead Pressure\\tWrite Pressure\");\n    \n    while (row = result.fetchOne()) {\n        print(`${row[0]}\\t${row[1]}\\t\\t${row[2]}\\t\\t${(row[3]*100).toFixed(2)}%\\t\\t${(row[4]*100).toFixed(2)}%`);\n    }\n}\nmodule.exports.analyzePerformanceTrends = analyzePerformanceTrends;<\/pre>\n<p>This function summarizes our collected data. It shows the average daily number of reads and writes and calculates the &#8220;pressure&#8221; on your system, which is the percentage of operations that were pending.<\/p>\n<p>To use these functions, you&#8217;d do something like this:<\/p>\n<ul>\n<li>Run <code>`setupPerformanceTracking()<\/code>` once to create your metrics table.<\/li>\n<li>Set up <code>`trackPerformance()`<\/code> to run every hour (or however often you like).<\/li>\n<li>Once a week (or whenever you want), run <code>`analyzePerformanceTrends()`<\/code> to see how things have been going.<\/li>\n<\/ul>\n<p>By tracking these metrics over time, you&#8217;ll be able to spot patterns. The key to good database management is being proactive. By keeping an eye on these trends, you&#8217;ll be able to address potential issues before they become real problems.<\/p>\n<h2><a id=\"post-105503-_heading=h.u9gl2c1k6n7o\"><\/a>Conclusion<\/h2>\n<p>We&#8217;ve covered a lot of ground today, exploring how to optimize disk I\/O and storage using MySQL Shell. From configuring InnoDB&#8217;s I\/O settings to adjusting data and log file sizes, monitoring disk performance, and optimizing individual tables, these optimizations can have a major impact on your MySQL server\u2019s performance.<\/p>\n<p>Remember, optimization is an ongoing process. As your database grows and its usage patterns change, regularly revisit these settings and adjust them as needed to maintain optimal performance. In the next article, we\u2019ll look at network and query performance optimization. We&#8217;ll use MySQL Shell to fine-tune network settings and learn how to identify and optimize slow queries. Stay tuned.<\/p>\n<h2><a id=\"post-105503-_heading=h.78xz2hnggtwh\"><\/a>Further Reading<\/h2>\n<p>To deepen your understanding of MySQL disk I\/O optimization, consider exploring these resources:<\/p>\n<ul>\n<li><a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/optimizing-innodb-diskio.html\">MySQL 8.0 Reference Manual: Optimizing InnoDB Disk I\/O<\/a><\/li>\n<li><a href=\"https:\/\/www.oreilly.com\/library\/view\/high-performance-mysql\/9781449332471\/\">High Performance MySQL: Optimization, Backups, and Replication<\/a> by Baron Schwartz, Peter Zaitsev, and Vadim Tkachenko<\/li>\n<li><a href=\"https:\/\/dev.mysql.com\/doc\/mysql-shell\/8.0\/en\/\">MySQL Shell 8.0 Manual<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>So far, in our previous articles on MySQL optimization, we&#8217;ve looked at basic configuration management and memory and CPU tuning using MySQL Shell. In the first article, we looked into how to optimize your MySQL database\u2019s configuration with MySQL Shell. In the second article, we focused on memory and CPU usage, showing how to monitor&#8230;&hellip;<\/p>\n","protected":false},"author":342096,"featured_media":105521,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[53,145792],"tags":[159266,5854],"coauthors":[159002],"class_list":["post-105503","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-mysql","tag-chisomkanu_mysqlshell","tag-mysql"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/105503","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/342096"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=105503"}],"version-history":[{"count":18,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/105503\/revisions"}],"predecessor-version":[{"id":105528,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/105503\/revisions\/105528"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/105521"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=105503"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=105503"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=105503"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=105503"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}