M4RKYU.SYSEdition 2027
Skip to content
LOCZH/安大略 · 加拿大/▸logs · mysql performance monitoring and query analysis 2co待机OK/--:--:--EST
M4M4RK_YUportfolio
  • 创作创作
    创作Overview
    • 作品精选案例与项目记录
    • 游戏可玩原型与游戏开发日志
  • 影像影像
    影像Overview
    • 照片影像合集与视觉实验
    • 商店印刷品、海报和限量物件
  • 写作写作
    写作Overview
    • 博客长篇开发日志与现场笔记
    • 笔记短观察、链接与代码片段
  • 资源资源
    资源Overview
    • 工具38 款浏览器内开发工具
    • 链接每日使用的开发与设计书签
  • 关于关于
  • 联系联系
EN

同步 · dev.to / @markyu

Debug a Slow MySQL Query Before You Guess at Indexes

A practical MySQL workflow for finding slow queries, reading EXPLAIN output, and deciding whether an index actually helps.

发布日期
May 20 '24
·
阅读时长
3 min read
·
点赞
13
·
评论数
2
mysqldatabasebackendperformance
在 dev.to 查看评论

本页目录

  • 1. Confirm MySQL Is Actually the Bottleneck
  • 2. Turn On the Slow Query Log
  • 3. Summarize the Worst Queries
  • 4. Run EXPLAIN on the Real Query
  • 5. Add the Index That Matches the Query
  • 6. Do Not Keep Every Index
  • 7. The Mistakes I See Most
  • My Checklist

The fastest way to make MySQL worse is to add indexes because a query "feels slow."

Start with evidence. Find the query. Measure it. Read the plan. Then change one thing.

Here is the workflow I use.

1. Confirm MySQL Is Actually the Bottleneck

Do not start inside EXPLAIN. First check if the database is under obvious stress.

SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Slow_queries';
SHOW GLOBAL STATUS LIKE 'Innodb_rows_read';
SHOW GLOBAL STATUS LIKE 'Com_select';

These numbers do not solve the problem, but they tell you where to look.

If Slow_queries is climbing during the incident, turn to the slow query log. If connections are spiking, you may have an app pooling problem. If rows read is exploding, you probably have missing selectivity or a bad access pattern.

2. Turn On the Slow Query Log

Check the current setting:

SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
SHOW VARIABLES LIKE 'slow_query_log_file';

Enable it for the running server:

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;

For persistent config, add this to your MySQL config:

slow_query_log = 1
long_query_time = 1
log_queries_not_using_indexes = 0

I usually avoid turning on log_queries_not_using_indexes at first. It can create noise. A query can skip indexes and still be fine on a small table. Start with actual slow queries.

3. Summarize the Worst Queries

Use mysqldumpslow when you need a quick local read:

mysqldumpslow -s t -t 10 /var/lib/mysql/*-slow.log

Useful sort modes:

mysqldumpslow -s t -t 10 /var/lib/mysql/*-slow.log  # total query time
mysqldumpslow -s at -t 10 /var/lib/mysql/*-slow.log # average query time
mysqldumpslow -s c -t 10 /var/lib/mysql/*-slow.log  # count

I care about two classes:

  • A query that runs rarely but takes forever.
  • A query that is individually mediocre but runs thousands of times.

Both can hurt production.

4. Run EXPLAIN on the Real Query

Say the slow log points to this:

SELECT id, title, published_at
FROM posts
WHERE author_id = 42
  AND status = 'published'
ORDER BY published_at DESC
LIMIT 20;

Run:

EXPLAIN
SELECT id, title, published_at
FROM posts
WHERE author_id = 42
  AND status = 'published'
ORDER BY published_at DESC
LIMIT 20;

The columns I check first:

ColumnWhat I look for
typeALL means full scan. Not always bad, but suspicious on large tables.
possible_keysIndexes MySQL could use.
keyThe index MySQL actually used.
rowsEstimated rows scanned.
ExtraWatch for Using filesort and Using temporary.

5. Add the Index That Matches the Query

For the query above, this is a practical index:

CREATE INDEX idx_posts_author_status_published
ON posts (author_id, status, published_at DESC);

Why this order?

  • author_id is an equality filter.
  • status is another equality filter.
  • published_at supports the sort after filtering.

Then run EXPLAIN again. If rows drops and the sort gets cheaper, you probably helped.

6. Do Not Keep Every Index

Indexes speed reads but slow writes and consume memory/disk. Every new index should pay rent.

Check existing indexes:

SHOW INDEX FROM posts;

If two indexes overlap, you may not need both.

Example:

INDEX (author_id)
INDEX (author_id, status, published_at)

The longer composite index can often satisfy lookups that start with author_id. Do not delete blindly, but do question duplicates.

7. The Mistakes I See Most

Adding an index on the wrong single column:

CREATE INDEX idx_posts_status ON posts (status);

If almost every row is published, this index is low value.

Using functions on indexed columns:

WHERE DATE(published_at) = '2026-06-16'

Prefer a range:

WHERE published_at >= '2026-06-16'
  AND published_at < '2026-06-17'

Selecting more columns than needed:

SELECT * FROM posts ...

Make the query say what the screen actually needs.

My Checklist

  • Find the slow query from logs, not vibes.
  • Reproduce the query with realistic parameters.
  • Run EXPLAIN.
  • Add one index that matches filters and sorting.
  • Run EXPLAIN again.
  • Measure the endpoint again.
  • Remove indexes that do not earn their cost.

Performance work is not magic. It is a loop: observe, change, measure.

相关阅读

Bad Data Quality Costs More Than a Slow Query

A practical data quality guide for engineers: validation, ownership, schema drift, observability, and fixing bad data before dashboards lie.

data

Java BeanUtils Copying: Convenient, but Not Free

A practical Java guide to BeanUtils, shallow copy pitfalls, reflection overhead, and when MapStruct or manual mapping is a better choice.

java

RedisJSON Is Useful When You Update Parts of a Document

A practical RedisJSON walkthrough: when to use it, when not to, and the commands that actually matter.

redis

原文发布

本文首发于 dev.to,评论与点赞保留在原站。

在 dev.to 继续阅读
上一篇CSS 3D Transform Bugs Usually Come From PerspectiveA practical CSS 3D transform guide explaining perspective, rotateX, rotateY, transform-style, backface visibility, and debugging layout.
返回全部文章
下一篇CSS Heart Animation: Small Demo, Real Animation LessonsA cleaner CSS heart animation tutorial focused on transform, pseudo-elements, keyframes, and the small mistakes that break simple UI animations.
返回档案
M4RKYUM4RKYUM4RKYUM4RKYUM4RKYUM4RKYUM4RKYUM4RKYU
始于 2024
ZhenXiao Mark YuZhenXiao Mark Yu
联系

看到什么有意思的?和我聊聊。

这是一个作品集,不是服务 · 但每一条留言我都会看 — 如果哪里让你有所触动,或者只想打个招呼,欢迎写信过来。

开启对话
频道开放

随时打个招呼 · 2026

--:--:--EST加拿大 安大略
  • 邮件
  • GitHub
  • dev.to
  • 领英
  • 推特 / X
  • Instagram
  • Facebook
  • YouTube
  • CodePen
  • Spotify
  • Snapchat

订阅

偶尔收到一封简讯

来自 m4rkyu.com 的笔记与日志——简短、标注日期、没有杂音。随时可退订。

作品

线上发布、游戏作品与视觉档案。

  • 项目
  • 游戏
  • 档案
  • 日志

资源

每日好用的工具与个人收藏的链接库。

  • 搜索
  • 最新
  • 工具
  • 链接
  • 笔记
  • 主题
  • 商店
RSSJSON Feed

工作室

背景、联系方式以及合作渠道。

  • 关于
  • 联系
  • 更新日志
  • 技术说明
  • 简历筹备中

社交

在常去的平台上找到我。

  • GitHub
  • dev.to
  • 领英
  • 推特 / X
  • Instagram
  • Facebook
  • YouTube
  • CodePen
  • Spotify
  • Snapchat
  • 邮件
© 2026 ZhenXiao Mark Yumarkyu0615@gmail.com
  • 邮件
  • GitHub
  • dev.to
  • 领英
  • 推特 / X
  • Instagram
  • Facebook
  • YouTube
  • CodePen
  • Spotify
  • Snapchat
隐私条款由 Next.js 16 · React 19 · Tailwind 4 构建