最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
MySQL 5.7中如何利用MRR多范围读取优化显著提升索引检索效率?
时间:2026-06-24 09:02:46 编辑:袖梨 来源:一聚教程网
必须组合验证:执行EXPLAIN FORMAT=JSON查"using_mrr": true,观察Extra是否含Using MRR或Using index condition; Using MRR,再结合sys.schema_table_statistics对比rnd_next与rnd_pos次数变化,才能确认MRR是否真实生效。
EXPLAIN里没出现Using MRR,不代表MRR没生效;真正起效的前提是:走二级索引 + 必须回表 + 主键值物理分布离散。
怎么确认当前查询到底用了MRR?
不能只看EXPLAIN输出的Extra列是否含Using MRR——它可能被隐藏或跳过。必须组合验证:
- 执行
EXPLAIN FORMAT=JSON,检查"mrr": true和"mrr_cost": xxx字段是否存在且为正数 - 观察
Extra列:出现Using index condition; Using MRR说明ICP和MRR同时启用;只有Using index condition而无MRR,大概率是read_rnd_buffer_size太小或预估行数低于阈值(默认约10行) - 用
SELECT * FROM sys.schema_table_statistics WHERE table_name = 'your_table'对比rnd_next(随机读)和rnd_pos(顺序读)次数变化,比单纯看执行时间更反映MRR真实作用
哪些WHERE条件能真正触发MRR?
MRR不是所有范围查询都管用,它只在满足“二级索引扫描 → 回表 → 主键离散”三要素时才被优化器考虑:
- 有效场景:
WHERE status IN (1,2,3)、WHERE created_at BETWEEN '2025-01-01' AND '2025-12-31' ORDER BY id LIMIT 100、WHERE category = 'A' AND price > 100(联合索引最左匹配后带范围) - 无效场景:
SELECT id, name FROM t WHERE status = 1(覆盖索引,无需回表)、SELECT * FROM t WHERE id > 1000(主键扫描,无二级索引参与)、WHERE JSON_CONTAINS(data, '"abc"')(虚拟列索引不支持MRR)
调大read_rnd_buffer_size就一定更快?
不一定,这个参数是一把双刃剑:
- 设太小(如默认256K):小结果集直接跳过MRR,走传统随机回表
- 设太大(如16M):单连接独占内存暴涨,高并发下易OOM;若二级索引本身很宽(比如含
TEXT列),排序开销可能反超IO节省 - 推荐实操值:先试
SET SESSION read_rnd_buffer_size = 4194304(4M),再结合sys.schema_table_statistics看rnd_next是否明显下降 - 注意:
read_rnd_buffer_size是会话级变量,改完必须在同session里跑EXPLAIN或真实查询才能验证效果
optimizer_switch里mrr和mrr_cost_based怎么配?
这两个开关控制MRR是否可选以及是否由成本驱动:
-
mrr=on是前提(MySQL 5.7默认开启),否则MRR根本不可用 -
mrr_cost_based=on(默认)表示优化器按成本估算决定是否启用MRR;设为off则强制启用,但容易在小结果集或宽索引场景下适得其反 - 调试时可用
SELECT @@optimizer_switch查看当前值;临时关闭MRR对比性能,可用SELECT /*+ NO_MRR(t) */ ...(MySQL 8.0.20+才支持,5.7不适用)
最容易被忽略的一点:启用MRR后EXPLAIN显示的rows可能突然变大——这不是变慢了,而是优化器在展示“排序前”的索引扫描行数,不是最终输出量。别因此误判优化失败。
相关文章
- 《和平精英》火箭少女皮肤怎么获得-火箭少女皮肤价格解析 06-25
- Vivacut怎么设置比例 06-25
- hive archive数据迁移如何进行 06-25
- hive archive能实现数据权限管理吗 06-25
- hive archive 如何执行数据统计 06-25
- hive archive能实现数据搜索吗 06-25