---
title: "MySQL 慢查询排查：从 EXPLAIN 到索引取舍"
date: 2026-02-20
category: "后端开发"
---

# MySQL 慢查询排查：从 EXPLAIN 到索引取舍

二月里发现文章列表偶尔要两三秒才出来。数据量明明不大，帖子才几十条，按理说不该这样。

开慢查询日志抓了一下，抓到这条：

```sql
SELECT * FROM posts WHERE status = 'published' ORDER BY published_at DESC LIMIT 20;
```

EXPLAIN 一看，type 是 ALL，全表扫描，Extra 里还有 Using filesort。数据少的时候全表扫描也快，所以之前一直没暴露。

建了一个联合索引，status 在前、published_at 在后，过滤和排序一起命中。再跑 EXPLAIN，type 变成 ref，rows 从全表降到 20。

顺手记两条当时踩的坑。

一是联合索引只认最左前缀。建了 (status, published_at) 之后，单独按 published_at 查是吃不到的，别指望索引自己猜。

二是深分页。LIMIT 100000, 20 这种写法，前面的十万行是实打实扫过的。后来列表改成游标方式，用上一页最后一条的时间做条件，翻再深都不掉速。

改完之后列表稳定在几十毫秒。优化这件事，EXPLAIN 比直觉靠谱。