mysql如何提高读取大表数据的效率_mysql大表优化策略

来源:这里教程网 时间:2026-02-28 20:51:20 作者:

EXPLAIN
看清查询到底在扫多少行

不看执行计划就调优,等于蒙眼修车。对大表查询,第一件事是加

EXPLAIN
前缀跑一遍,重点盯
rows
type
字段:
-
rows
显示预估扫描行数,如果远大于结果集行数,说明索引没生效或用了低效索引
-
type
ALL
(全表扫描)或
index
(全索引扫描),基本等于性能红灯
-
key
为空,或
key_len
远小于预期,常因查询条件没用上联合索引最左前缀

联合索引设计必须匹配查询模式

大表上建单列索引效果有限,关键在让索引覆盖查询条件 + 排序 + 返回字段:
- 条件中有

WHERE a = ? AND b > ? ORDER BY c
,索引应为
(a, b, c)
,顺序不能错
- 如果还要
SELECT d, e
,考虑加
INCLUDE
(MySQL 8.0.13+ 支持)或直接建覆盖索引
(a, b, c, d, e)

- 避免在索引列上做函数操作,比如
WHERE YEAR(created_at) = 2023
会让索引失效,改用
created_at BETWEEN '2023-01-01' AND '2023-12-31'

分页深翻时别用
LIMIT offset, size

offset
超过几十万,MySQL 仍要从头扫描并丢弃前面所有行,I/O 和 CPU 开销陡增:
- 改用游标分页:记录上一页最后一条的主键值,下一页查
WHERE id > last_id ORDER BY id LIMIT 100

- 若业务允许,用
WHERE create_time > ? ORDER BY create_time LIMIT 100
替代基于偏移的分页
- 禁止在管理后台写
LIMIT 1000000, 20
—— 这类语句应加权限拦截或走异步导出

读多写少场景可考虑物化视图替代实时聚合

对大表频繁执行

GROUP BY + COUNT/SUM
,即使加了索引,每次查询仍要遍历大量数据:
- MySQL 本身不支持物化视图,但可用定时任务把聚合结果写入汇总表,比如每小时跑一次
INSERT INTO summary_daily SELECT date(created_at), COUNT(*) FROM big_table GROUP BY date(created_at)

- 查询时直接查汇总表,响应时间从秒级降到毫秒级
- 注意汇总表和源表的数据一致性,避免用
REPLACE INTO
ON DUPLICATE KEY UPDATE
时漏更新

实际优化中,最常被忽略的是查询与索引的“严丝合缝”——差一个字段顺序、多一个函数包装、少一个

ORDER BY
字段,索引就形同虚设。大表不是靠堆硬件扛住的,是靠让每一行扫描都算得上。

相关推荐