Learn MySQL Performance
Efficient MySQL Performance distills 20 years of MySQL expertise into 344 pages. Written for software developers, not DBAs, it's easy to digest even if you're new to MySQL.
The nine-step path below is an efficient way through the jungle of MySQL performance topics. Avoid pitfalls! Learn these topics in this order, which is (not coincidentally) the same order as chapters in the book.
"Daniel does a great job of showing how to drive to the fastest resolution without getting lost in guesswork. He also covers InnoDB row locking in a detailed yet digestible form."
—Vadim Tkachenko, CTO, Percona
"This book is different from other MySQL books—it focuses on what matters most: query response time. A must-have for MySQL users!"
—Frédéric Descamps, MySQL Community Manager, Oracle Belgium
"Hands down [the] best technical book I've ever read, and I've been working in this field for close to 30 years."
—Adam (verified Amazon review)
Extremely well written and accessible —reddit comment
MySQL Articles
mlrd ("mallard") is a DynamoDB-compatible API that runs on MySQL.
A nine-step learning path through MySQL performance in the same order as Efficient MySQL Performance, designed to be the most efficient route to learn MySQL performance.
With multi-threaded replication, Seconds_Behind_Source is no longer a reliable lag metric. Part 1 of a 3-part series on monitoring lag correctly with Performance Schema tables.
replica_preserve_commit_order determines whether a replica commits transactions in source order under multi-threaded replication, with consequences for how lag is measured.
All 10 chapters of Efficient MySQL Performance, from "Performance is query response time" to the final chapter, each distilled to a single sentence.
Part 1 of 3: understanding binary log group commit and transaction dependency tracking, the foundation for how multi-threaded replication works in MySQL 8.0.
Reflections on 20 years hacking MySQL and software engineering.
A relational database is more than a data bank: it's applied philosophy. The second and final part of lessons from 20 years hacking MySQL.
Replication lag gets all the attention, but MySQL replication is actually remarkably fast. A controlled experiment with Performance Schema and binary log inspection shows exactly why.
When COMMIT appears as your slowest query, the root cause is almost always slow storage. Here's how to confirm it and what to do about it.
For 16 years the MySQL query optimizer has had a bug where LIMIT 1 can be slower than LIMIT 20 and even trigger a full table scan. Here's what's happening and why.
Spirit is a new online schema change tool by MySQL expert Morgan Tocker, built to improve on both pt-online-schema-change and gh-ost in speed and safety.
Deferred join is an SQL rewrite that can make a paginated query 2x faster or more, but it's widely misunderstood. This deep dive shows exactly how and why it works.
Finch is a new declarative MySQL benchmarking tool for experts and modern infrastructure, designed to handle the workloads and flexibility that sysbench cannot.
Amazon claims Aurora delivers "Up to 5X the throughput of MySQL." Deep benchmarking digs past the marketing to find out if it's actually true.
Blip is a new MySQL monitor that rethinks metrics collection from the ground up, solving problems that existing open-source monitors don't address.
COMMIT is when MySQL pays the storage latency cost to make writes durable. Benchmarking Aurora v2, Aurora v3, and RDS MySQL 8.0 reveals how much that cost differs across AWS managed databases.
Blip v1.0.0 ships: an open-source MySQL metrics collector purpose-built from the ground up to be the last and greatest MySQL monitor ever.
MySQL I/O tuning focuses almost entirely on writes, but read IOPS and a few surprising I/O behaviors are worth understanding too.
Cloud MySQL changes the DBA role but doesn't end it, and the implications for software engineers using (not managing) MySQL are significant.
The unwritten chapter 9 of Efficient MySQL Performance: how not to use MySQL, including the ways MySQL's reliability makes it too easy to misuse.
The Performance Schema holds a rich history of transaction execution: query timings, idle gaps, and more. This post shows how to mine it for a transaction report MySQL tooling doesn't provide.
MySQL transactions are important but almost nobody monitors them. This post explores what the Performance Schema makes possible and why transaction reporting tooling barely exists.
Heartbeat tables have measured MySQL replication lag for over a decade, but with multi-threaded replication (MTR) the approach has limitations. Can we do better?
InnoDB page flushing is one of MySQL's most complex internals. This post diagrams the whole process in one visual.
Sharding MySQL is a last resort, not a first move. Let's look at why engineers reach for sharding prematurely and what to try instead.
Access patterns are talked about constantly but rarely enumerated. This post catalogues the specific ways applications access MySQL and why each one matters for performance.
MySQL performance is about doing less, not more. A look at why reducing what MySQL does is the most powerful performance strategy.
EXPLAIN ANALYZE is indispensable for understanding query execution, but its output isn't easy to interpret. This post closely examines three real examples of its output.
Configuring MySQL query metrics (slow query log, Performance Schema) is skipped in most books but critical in practice. This post covers what chapter 1 of Efficient MySQL Performance left out.
After 17 years with MySQL, I wrote a book unlike any MySQL book before, focused on what actually matters for engineers, not DBAs.
InnoDB background LRU flushing is not constrained by innodb_io_capacity or innodb_io_capacity_max. Here's the proof.
MySQL 8.0 moved data lock information to performance_schema.data_locks. A visual mapping shows how the new output corresponds to what used to be buried in SHOW ENGINE INNODB STATUS.
Automating MySQL password rotation at scale with AWS Secrets Manager, Lambda, and Terraform is far more complex than it appears. Here's a detailed guide that covers all of it.
What does a production-ready query metrics system actually need?
A technical deep dive into InnoDB dirty page flushing: what it is, what controls it, and why tuning it matters for consistent MySQL write performance.
21 MySQL 5.7 system variables to change from their RDS defaults, with the MySQL default, the AWS default, and the recommended value.
GTID auto-positioning makes failover feel safe, but it can silently accept a replica that missed writes from a crashed primary. Here's how to detect the data loss.
QPS measures throughput, but Threads_running reveals how hard MySQL is actually working. It's one of the most important MySQL metrics to monitor.
Queries don't merely affect MySQL performance, they are the cause of it. When hardware is healthy, queries are responsible for performance, which means they can also fix it.
Ghosted GTIDs—gaps in the executed GTID set silently break auto-positioning and replication topology changes. Here's how to detect them and fix them.
Handling MySQL connection errors in Go requires dealing with server error codes, driver errors, sql package errors, and network errors all at once. A practical guide to getting it right.
Crash-safe replication is widely misunderstood; most guides add unnecessary settings. This visual guide shows exactly which configuration is necessary and sufficient.
MySQL Select% and Sort% status variables are ancient diagnostics that remain essential for understanding query performance. This is the updated guide for MySQL 8.0.
