Skip to content

Chapter 7 of 7

Monitoring, Scaling, and Operational Practices

Effective monitoring is what turns ad hoc optimization into a sustainable practice. The slow query log is a foundational tool: enabled with `slow_query_log` and thresholded by `long_query_time`, it records queries that exceed a configurable time or that do not use indexes (`log_queries_not_using_indexes`). Analyzing the slow query log regularly — to rank queries by impact and identify patterns — is how teams prioritize optimization work. The `performance_schema` and the convenience `sys` schema provide rich, structured metrics on statement execution, waits, locks, IO, and memory, with views that aggregate top queries by digest, expose index usage, and highlight hotspots. Watch for tail latencies (p95, p99) rather than only averages, and look at indicators like `Handler_read_rnd_next` (high values suggest full scans), `Created_tmp_disk_tables` (signals queries spilling to disk), and the ratio of `rows_examined` to `rows_sent` (large ratios mean wasted work). Be aware that extensive `performance_schema` instrumentation has overhead, so enable instruments selectively based on what you need to observe.

Scaling patterns extend performance beyond a single server. Replication copies changes from a primary to one or more replicas, allowing read traffic to be offloaded and reporting or analytical workloads to be isolated. When offloading reads, you must account for replication lag, because replicas may be slightly behind the primary. Row-based replication is generally more predictable for complex queries than statement-based replication. GTID-based replication simplifies failover and resharding by uniquely tracking transactions, and semisynchronous replication trades a small amount of commit latency for reduced data loss risk. Group Replication and similar cluster technologies provide automatic failover at the cost of coordination overhead on writes. Beyond replication, sharding splits data across independent databases or servers, typically by key, to scale writes and storage — at the cost of cross-shard query complexity. Read/write splitting through connection pools or proxy layers (such as ProxySQL or MaxScale) provides much of the benefit of sharding for read-heavy systems without changing application code. Connection pooling at the application or proxy layer is widely preferred over raising `max_connections` very high, because too many concurrent connections consume memory and increase context switching; capping connections per application instance and using exponential backoff on retries also helps prevent connection storms during spikes or deploys.

Operational discipline ties everything together. Before changing configuration or schema in production, test in a staging environment, capture before-and-after metrics, and have a rollback plan. Roll out changes gradually, use feature flags to expose risky optimizations to a small percentage of traffic, and validate with EXPLAIN plans and key query metrics. When adding indexes, test EXPLAIN both before and after to confirm the optimizer actually uses the new index, and use read-only replicas to experiment with index changes safely. For large tables, online DDL with explicit ALGORITHM and LOCK clauses lets you choose how disruptive a schema change will be, but always test on representative data because some operations still require long metadata locks or significant temporary space. Be cautious with `OPTIMIZE TABLE` on large production tables, since it can require locks and substantial disk space; prefer targeted maintenance windows or, where possible, partitioning with sliding windows to drop old data quickly. Heavy OLAP queries should run on dedicated replicas or a separate cluster tuned for large scans, because mixing them with OLTP traffic on the same instance tends to monopolize CPU, IO, and the buffer pool, hurting user-facing latency. Backup strategy also matters: physical hot backups, taken from replicas and scheduled off-peak, are usually lighter on the primary than logical dumps during peak hours.

Finally, the larger context matters. Insufficient CPU, RAM, disk IOPS, or network bandwidth can bottleneck even a perfectly tuned schema and query set. Memory pressure that causes swapping is a common silent killer of latency, as is running on slow or shared networked storage. NUMA architectures can introduce remote memory access costs that are mitigated by binding MySQL to specific CPUs and memory nodes or by configuring interleaved allocation. Containerized deployments require careful sizing, dedicated fast persistent storage, and avoidance of noisy neighbors and frequent restarts. Most importantly, treat optimization as an ongoing, business-driven practice: tie work to user-visible metrics, document the reasoning behind indexes and configuration choices, schedule regular performance reviews of key queries, and keep the discipline of measuring, changing one thing, verifying, and iterating based on real workload behavior.

All chapters
  1. 1Foundations, Measurement, and the Optimization Mindset
  2. 2Reading Execution Plans with EXPLAIN
  3. 3Indexing for Performance
  4. 4Writing Efficient Queries
  5. 5Schema Design, Data Types, and Table Structure
  6. 6InnoDB Internals, Configuration, and Concurrency
  7. 7Monitoring, Scaling, and Operational Practices

Drill it

Reading is not remembering. These come from the MySQL Optimization Anki deck:

Q

What is the primary goal of MySQL optimization?

To reduce query response times, resource usage, and improve scalability by tuning schema, queries, indexes, and configuration.

Q

What are the main areas involved in MySQL performance optimization?

Schema design, indexing, query writing, configuration tuning, hardware resources, and monitoring.

Q

Why is it important to measure performance before optimizing?

Because you need a baseline to compare improvements against and to avoid optimizing the wrong parts of the system.

Q

Which MySQL command provides a detailed execution plan for a SELECT query?

EXPLAIN