MySQL 5.7与8.0在索引优化器算法上有什么显著改进?

雨晨大大_7769

雨晨大大_7769

2026-06-02

366人浏览

原创

mysql 8.0 的 cost model 基于统计信息动态估算 i/o 和 cpu 成本选择索引,而非 5.7 的固定规则;若未执行 analyze table 导致统计陈旧,反而引发执行计划劣化。

mysql 5.7与8.0在索引优化器算法上有什么显著改进?

MySQL 8.0 的 Cost Model 怎么影响索引选择

5.7 的优化器基本靠“有索引就走索引”这类固定规则,不评估实际代价;8.0 默认启用 Cost Model,会基于统计信息估算不同索引路径的 I/O 和 CPU 成本,再选总 cost 更低的方案。比如 WHERE a = ? AND b > ?,5.7 可能死守 idx_a,而 8.0 会权衡用 idx_a 还是 idx_b 或联合索引更省。

但这个机制依赖准确的统计信息:不跑 ANALYZE TABLE,Cost Model 就会瞎估——升级后执行计划反而变差,常见于大表未及时更新统计信息的场景。

  • SELECT @@optimizer_switch LIKE '%cost_model=on%' 检查是否启用
  • EXPLAIN FORMAT=TREE 在 8.0 中可直接看到各节点预估 cost 值,5.7 不支持
  • 强制关闭仅用于调试:SET optimizer_switch='cost_model=off'

函数索引和降序索引在 8.0 中真能生效吗

5.7 对 CREATE INDEX idx ON t ((UPPER(name))) 直接报 ERROR 1064,因为解析器根本不认函数表达式;8.0.13+ 才真正支持双括号语法,且底层自动映射为不可见虚拟列 + B+ 树索引——但它仍受限于 B+ 树特性,只对 UPPER(name) = 'ABC' 有效,对 UPPER(name) LIKE '%abc%' 无效。

降序索引同理:5.7 允许写 INDEX (a DESC, b ASC),但 SHOW CREATE TABLE 会悄悄抹掉 DESC,实际仍是升序组织;8.0 是物理级降序存储,ORDER BY a DESC, b ASC 才能免 Using filesort,但前提是 WHERE 条件覆盖最左前缀(如 WHERE a > 100)。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
  • 方向必须严格一致:查询 ORDER BY a DESC, b DESC 而索引是 (a DESC, b ASC),不命中
  • 函数必须确定性:NOW()、RAND() 等非确定函数不允许建函数索引
  • 空格、括号嵌套层级都要和索引定义完全一致,不是模糊匹配

为什么 8.0 的子查询索引利用更可靠

5.7 中 IN 或 = 后跟子查询,只要引用外层字段(如 WHERE t1.id = (SELECT ref_id FROM t2 WHERE t2.id = t1.id)),就大概率标记为 DEPENDENT SUBQUERY,导致外层每行都重执行一次子查询,I/O 爆炸;8.0 引入基于代价的物化决策(subquery_materialization_cost_based=ON),并支持 /*+ MATERIALIZE */ 提示,让子查询结果一次性计算、后续哈希连接。

但别默认它“自动生效”:标量子查询(如 SELECT (SELECT name FROM users WHERE id = o.user_id))仍不会物化,必须手动改写;且物化临时表受 sort_buffer_size 和 join_buffer_size 影响更大——缓冲区太小会退化为磁盘临时表,比 5.7 更卡。

  • 盯住 EXPLAIN FORMAT=TREE 输出里有没有 materialize 节点
  • 检查物化后的 rows 估算是否合理,否则提示可能被绕过
  • 升级后若发现慢查询变多,先确认是否因物化策略变化导致计划回退

不可见索引和隐藏索引的实际用途是什么

INVISIBLE 索引不是性能功能,而是灰度验证工具:设为不可见后,优化器彻底不选它,但索引照常维护、占用空间、不影响 ANALYZE TABLE 统计。你可以先 ALTER TABLE t1 ALTER INDEX idx_c1 INVISIBLE,观察慢查询是否复现,再决定删还是留。

5.7 完全不识别 INVISIBLE 语法,加了就报错;8.0 支持建表时指定或运行时修改。但容易忽略的是:不可见索引仍拖慢写入(INSERT/UPDATE 仍要更新它),且 mysqldump 默认导出时带 INVISIBLE 属性——若恢复到 5.7 库,直接失败。

  • 建表时声明:KEY idx_c1 (c1) INVISIBLE
  • SHOW INDEX FROM t1 的 Visible 列为 NO 即表示隐藏
  • 它不解决性能问题,只解决“删错索引导致某条报表 SQL 突然变慢几秒”的生产事故风险
真正关键的不是版本号,而是你是否在升级后重新校准了统计信息、是否检查了 EXPLAIN FORMAT=TREE 的 cost 估算与物化行为、是否意识到函数索引和降序索引的匹配是字面级严格的。这些点一旦漏掉,8.0 的新能力反而会成为性能陷阱。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4023

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

851

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1049

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5881

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2803

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5860

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7801

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1070

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

932

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 180人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 287人学习