Home/Learn/MySQL/MySQL Configuration Tuning

MySQL Configuration Tuning

Advanced
Administration

Key InnoDB variables: innodb_buffer_pool_size (60–80% of RAM), innodb_log_file_size, max_connections, thread_cache_size — benchmark with sysbench before and after tuning.

Overview

MySQL performance tuning centers on a small set of high-impact configuration variables. The most important is innodb_buffer_pool_size — the in-memory cache for InnoDB data and index pages. A well-sized buffer pool eliminates most disk I/O; the hit ratio should exceed 99% in production. Other critical settings: innodb_redo_log_capacity (write throughput and crash recovery speed), max_connections (connection overhead), thread_cache_size (reduce thread creation overhead), and query_cache (removed in 8.0 — use application-level caching instead). Always benchmark before and after tuning with a representative workload using sysbench or your own workload replay.

InnoDB buffer pool — the most important setting

The buffer pool caches data and index pages in memory — the larger it is, the more data is served from RAM rather than disk. Set it to 60–80% of total RAM (leave room for OS, connections, and temp tables). On machines with > 1 GB RAM, use multiple buffer pool instances (innodb_buffer_pool_instances) to reduce mutex contention. Monitor the buffer pool hit ratio — it should be > 99%.

Config + SQL — buffer pool sizing and hit ratio monitoring
# my.cnf — InnoDB buffer pool configuration
[mysqld]
# Set to 60-80% of available RAM
# Example: 16 GB server → 10-12 GB buffer pool
innodb_buffer_pool_size = 10G

# Multiple instances reduce mutex contention (1 per 1 GB)
innodb_buffer_pool_instances = 10

# Warm buffer pool on restart (avoids cold-start I/O storm)
innodb_buffer_pool_dump_at_shutdown = ON
innodb_buffer_pool_load_at_startup = ON

# Monitor buffer pool hit ratio
SELECT
    (1 - (SELECT variable_value FROM performance_schema.global_status
          WHERE variable_name = 'Innodb_buffer_pool_reads') /
         (SELECT variable_value FROM performance_schema.global_status
          WHERE variable_name = 'Innodb_buffer_pool_read_requests')
    ) * 100 AS buffer_pool_hit_ratio_pct;
-- Target: > 99%

# Shortcut via sys schema
SELECT * FROM sys.innodb_buffer_stats_by_schema
ORDER BY pages_allocated DESC LIMIT 10;

Redo log, connections, and write performance

The InnoDB redo log (write-ahead log) determines crash recovery speed and write throughput. Larger redo log = higher write throughput but slower crash recovery. MySQL 8.0.30+ uses innodb_redo_log_capacity (replaces the old innodb_log_file_size). max_connections limits concurrent connections (each uses ~1 MB RAM). thread_cache_size caches idle threads to avoid OS thread creation overhead.

Config + SQL — redo log, connection limits, and durability settings
# my.cnf — write performance and connection tuning
[mysqld]
# Redo log capacity (MySQL 8.0.30+)
innodb_redo_log_capacity = 4G   # larger = better throughput, slower recovery
# Older MySQL: innodb_log_file_size = 1G  (redo log = 2 × log_file_size)

# Durability vs performance trade-off
innodb_flush_log_at_trx_commit = 1   # safest: flush to disk on every commit
# = 2: flush to OS buffer on commit (lose up to 1s on crash)
# = 0: flush every second (lose up to 1s on crash + OS crash)
sync_binlog = 1                       # flush binlog to disk on every commit

# Connection tuning
max_connections = 500             # max concurrent connections
thread_cache_size = 50            # cache 50 idle threads (reduce thread creation)
wait_timeout = 600                # close idle connections after 10 min
interactive_timeout = 600

# I/O method (Linux) — O_DIRECT bypasses OS page cache (reduces double buffering)
innodb_flush_method = O_DIRECT

# Check current connection overhead
SHOW STATUS LIKE 'Threads_created';    # high = thread_cache too small
SHOW STATUS LIKE 'Connections';        # total connection attempts
SHOW STATUS LIKE 'Max_used_connections';  # peak simultaneous connections

Query optimiser settings and temp table configuration

The optimiser uses statistics to choose query plans. optimizer_switch controls which optimisation features are active. tmp_table_size and max_heap_table_size control in-memory temp table size — if a temp table exceeds this, it spills to disk (visible as Created_tmp_disk_tables in SHOW STATUS). Increase these values if EXPLAIN shows "Using temporary; Using filesort" frequently.

Config + SQL — temp table sizing and spill diagnosis
# my.cnf — temp tables and optimizer settings
[mysqld]
# Temp table memory limits
tmp_table_size = 256M           # max in-memory temp table size
max_heap_table_size = 256M      # must match tmp_table_size

# Join buffer for non-indexed joins
join_buffer_size = 4M           # per-join allocation (not global pool)

# Sort buffer
sort_buffer_size = 4M           # per-sort allocation

# Key buffer (MyISAM only — for InnoDB, use buffer pool)
key_buffer_size = 32M

# Check if temp tables are spilling to disk
SHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables';   # spilled to disk
SHOW GLOBAL STATUS LIKE 'Created_tmp_tables';         # total temp tables
# Ratio: disk / total > 10% → increase tmp_table_size

# EXPLAIN to check sorts and temp tables
EXPLAIN SELECT customer_id, COUNT(*) FROM orders
GROUP BY customer_id ORDER BY COUNT(*) DESC;
-- "Using temporary; Using filesort" = memory temp table + sort
-- Increase tmp_table_size or add a covering index

Key Points to Remember

  • 1innodb_buffer_pool_size is the single most impactful setting — set to 60–80% of RAM; buffer pool hit ratio should be > 99%
  • 2innodb_redo_log_capacity controls write throughput — larger = faster writes, but longer crash recovery on restart
  • 3innodb_flush_log_at_trx_commit=1 + sync_binlog=1 is the safest durability setting, at a throughput cost
  • 4max_connections × ~1 MB RAM = total memory for connections — do not set to 10,000 on a 16 GB server
  • 5tmp_table_size controls when temp tables spill to disk — monitor Created_tmp_disk_tables / Created_tmp_tables ratio
  • 6Always benchmark with sysbench or application workload replay before and after tuning to verify improvement

Interview Questions

Sign in to ask Aria
1

What is innodb_buffer_pool_size and how would you size it for a 32 GB server running only MySQL?

MediumOracle
2

What do the different values of innodb_flush_log_at_trx_commit mean and what are the trade-offs?

HardAmazon
3

How would you detect if temp tables are spilling to disk and what configuration change helps?

MediumFlipkart
4

Why should max_connections not simply be set to a very large number?

MediumBooking.com
5

What is the buffer pool hit ratio and what does a low value (< 95%) indicate?

EasyThoughtworks

Ask Aria about MySQL Configuration Tuning

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…