Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >「Mysql索引原理(十六)」维护索引和表-更新索引统计信息

「Mysql索引原理(十六)」维护索引和表-更新索引统计信息

作者头像
源码之路
发布于 2020-09-04 02:13:47
发布于 2020-09-04 02:13:47
2.1K00
代码可运行
举报
文章被收录于专栏:源码之路源码之路
运行总次数:0
代码可运行

MySQL的査询优化器会通过两个API来了解存储引擎的索引值的分布信息,以决定如何使用索引。第一个API是 records_in_range(),通过向存储引擎传入两个边界值获取在这个范围大概有多少条记录。对于某些存储引擎,该接口返回精确值,例如MyISAM;但对于另一些存储引擎则是一个估算值,例如 InnoDB。 第二个API是info(),该接口返回各种类型的数据,包括索引的基数(每个键值有多少条记录)。 如果存储引擎向优化器提供的扫描行数信息是不准确的数据,或者执行计划本身太复杂以致无法准确地获取各个阶段匹配的行数,那么优化器会使用索引统计信息来估算扫描行数。 MySQL优化器使用的是基于成本的模型,而衡量成本的主要指标就是一个查询需要扫描多少行。如果表没有统计信息,或者统计信息不准确,优化器就很有可能做出错误的决定。可以通过运行ANALYZE TABLE来重新生成统计信息解决这个问题。 每种存储引擎实现索引统计信息的方式不同,所以需要进行ANALYZE TABLE的频率也因不同的引擎而不同,每次运行的成本也不同:

  1. Memory引擎根本不存储索引统计信息。
  2. MyISAM将索引统计信息存储在磁盘中, ANALYZE TABLE需要进行一次全索引扫描来计算索引基数。在整个过程中需要锁表。
  3. 直到 My SQL5.5版本,InnoDB也不在磁盘存储索引统计信息,而是通过随机的索引访问进行评估并将其存储在内存中。 可以使用 SHOW INDEX FR0M命令来查看索引的基数( Cardinality)。例如
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> SHOW INDEX FROM people

image.png

这个命令输出了很多关于索引的信息,在MySQL手册中对上面每个字段的含义都有详细的解释。这里需要特别提及的是索引列的基数(Cardinality),其显示了存储引擎估算索引列有多少个不同的取值。在 MySQL5.0和更新的版本中,还可以通过

FORMATION_SCHEMA. STATISTICS表很方便地查询到这些信息。例如基于 INFORMATION_SCHEMA的表,可以编写一个查询给出当前选择性比较低的索引。需要注意的是,如果服务器上的库表非常多,则从这里获取元数据的速度可能会非常慢,而且会给 MySQL带来额外的压力。

InnodB的统计信息值得深入研究。 InnoDB引擎通过抽样的方式来计算统计信息,首先随机地读取少量的索引页面,然后以此为样本计算索引的统计信息。在老的 InnodB版本中,样本页面数是8,新版本的 InnoDB可以通过参数 innodb_stats_sample_pages来设置样本页的数量。设置更大的值,理论上来说可以帮助生成更准确的索引信息,特别是对于某些超大的数据表来说,但具体设置多大合适依赖于具体的环境。

InnoDB会在表首次打开,或者执行 ANALYZE TABLE,抑或表的大小发生非常大的变化(大小变化超过十六分之一或者新插入了20亿行都会触发)的时候计算索引的统计信息。

InnoDB在打开某些INF0RMATION_SCHEMA表,或者使用 SHOW TABLE STATUS和SHOW INDEX,抑或在MySQL客户端开启自动补全功能的时候都会触发索引统计信息的更新。如果服务器上有大量的数据,这可能就是个很严重的问题,尤其是当IO比较慢的时候。客户端或者监控程序触发索引信息采样更新时可能会导致大量的锁,并给服务器带来很多的额外压力,这会让用户因为启动时间漫长而沮丧。只要SHOW INDEX查看索引统计信息,就一定会触发统计信息的更新。可以关闭 innodb_stats_on_metadata参数来避免上面提到的问题。

如果想要更稳定的执行计划,并在系统重启后更快地生成这些统计信息,那么可以使用系统表来持久化这些索引统计信息。甚至还可以在不同的机器间迁移索引统计信息,这样新环境启动时就无须再收集这些数据。在官方的5.6版本都已经加入这个特,通过innodb_analyze_is_persistent参数控制。

一旦关闭索引统计信息的自动更新,那么就需要周期性地使用ANALYZE TABLE来手动更新。否则,索引统计信息就会永远不变。如果数据分布发生大的变,可能会出现一些很糟糕的执行计划。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MySQL选错索引了怎么办?
在 MySQL 中一张表是可以支持多个索引的。但是,你写 SQL 语句的时候,并没有主动指定使用哪个索引。也就是说,使用哪个索引是由 MySQL 来确定的。
程序猿川子
2025/04/21
670
MySQL选错索引了怎么办?
MySQL优化器之Cardinality(Analyze table)
选择索引是优化器的工作,而优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句。在数据库里面,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着访问磁盘数据的次数越少,消耗的 CPU 资源越少。当然,扫描行数并不是唯一的判断标准,优化器还会结合是否使用临时表、是否排序等因素进行综合判断。
Power
2025/03/01
1220
show index from 及analyze table 详解
https://mp.weixin.qq.com/s/1MsyxhtG6Zk3Q9gIV2QVbA
保持热爱奔赴山海
2019/09/17
1.1K0
MySQL 8.0 InnoDB 的统计信息机制优化
MySQL 的InnoDB引擎会维护着用户表每个索引的统计信息,来帮助查询优化器选择最优的执行计划,详细的来说,key的分布情况能决定多表join的顺序,也能够决定查询使用哪一个索引。这些统计信息可以由专门的后台线程刷新,也可以由用户也可以显示的调用Analyze table的命令来刷新统计信息,本文基于最新的 MySQL 8.0 来具体分析一下刷新统计信息的具体实现。
用户1278550
2024/01/04
4080
MySQL 8.0 InnoDB 的统计信息机制优化
MySQL为什么会选错索引
MySQL server层的优化器负责选择索引。而优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句。在数据库里面,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着访问磁盘数据的次数越少,消耗的 CPU 资源越少。当然,扫描行数并不是唯一的判断标准,优化器还会结合是否使用临时表、是否排序等因素进行综合判断。
只喝牛奶的杀手
2021/10/14
1K0
MySQL如何评估索引的合理性?
我们都知道,在关系型数据库中,索引的存在是非常重要的,但是不合理的索引反而会影响到业务的性能,那怎么才能合理的设计索引也是业务高效访问数据库需要考虑的?如何才能评估索引创建的合理呢?今天我们给出其中一个评估指标:Cardinality
二货哈
2022/03/23
5840
深入理解MySQL8.0直方图
墨墨导读:MySQL 8.0 新功能直方图,继承于Oracle ,MairaDB的实现方式。本文从MySQL角度解释,直方图是什么。
数据和云
2020/07/10
1.4K0
深入理解MySQL8.0直方图
GreatSQL统计信息维护管理
非持久化统计信息的缺点显而易见,数据库重启后如果大量表开始更新统计信息,会对实例造成很大影响,所以目前都会使用持久化统计信息。 2、持久化统计信息在以下情况会被自动更新:
老叶茶馆
2024/05/18
950
GreatSQL统计信息维护管理
150道MySQL高频面试题,学完吊打面试官--InnoDB索引与MyISAM索引实现的区别+一个表中如果没有创建索引,那么会创建B+树吗
本专栏为150道MySQL大厂高频面试题讲解分析,这些面试题都是通过MySQL8.0官方文档和阿里巴巴官方手册还有一些大厂面试官提供的资料。 MySQL应用广泛,在多个开发语言中都处于重要地位,所以最好都要掌握MySQL的精华面试题,这也是面试官最喜欢问的,现在面试官在面试的时候更关心的是某个技术点的深度,所以专栏的内容也会从底层开始讲解,本专栏会一直不断的进行更新,欢迎大家一起交流学习。
小白的大数据之旅
2024/11/20
1270
150道MySQL高频面试题,学完吊打面试官--InnoDB索引与MyISAM索引实现的区别+一个表中如果没有创建索引,那么会创建B+树吗
MySQL自动索引选择机制与优化方法(4/16)
MySQL会在某些情况下选择错误索引导致查询性能下降。例如不断地删除历史数据和新增数据的场景。
十里桃花舞丶
2024/04/12
4890
MySQL自动索引选择机制与优化方法(4/16)
MySQL索引选择底层原理探究-从一个慢查询说起 | 技术创作特训营第一期
在生产环境中收到一个接口耗时预警, 通过监控发现, 接口耗时达到了89s, 最终定位到了是因为触发了一个sql慢查询场景.
一笑而过zdp
2023/08/25
5.2K28
MySQL索引选择底层原理探究-从一个慢查询说起 | 技术创作特训营第一期
MySQL索引选择规划
通过explain的执行结果我们可以看出,上面的SQL语句并没有走我们的索引a,而是直接使用了全表扫描。
shysh95
2022/02/16
1.1K0
MySQL索引选择规划
MySQL开发中易忽略知识总结-0
在可重复读隔离级别下,事务在启动的时候就拍另一个快照。注意,这个快照时基于整库的。
用户2032165
2019/03/04
1K0
MySQL开发中易忽略知识总结-0
mysql为什么选错索引?怎么解决?
在进行慢SQL分析的时候,有时候我们会发现explain的扫描行数和慢日志中的行数相差很大,那explain中的rows这个扫描行数是怎么判断的?
不吃西红柿
2022/07/29
5460
统计信息记录表|全方位认识 mysql 系统库
在上一期《数据库对象信息记录表|全方位认识 mysql 系统库》中,我们详细介绍了mysql系统库中的元数据记录表,本期我们将为大家带来系列第四篇《统计信息记录表|全方位认识 mysql 系统库》,下面请跟随我们一起开始 mysql 系统库的系统学习之旅吧。
老叶茶馆
2020/12/15
1.1K0
MySQL深入学习第十篇-MySQL为什么有时候会选错索引?
前面我们介绍过索引,你已经知道了在 MySQL 中一张表其实是可以支持多个索引的。但是,你写 SQL 语句的时候,并没有主动指定使用哪个索引。也就是说,使用哪个索引是由 MySQL 来确定的。
越陌度阡
2020/11/26
4120
MySQL深入学习第十篇-MySQL为什么有时候会选错索引?
MYSQL 索引优化
提升SELECT 的最好方式是使用索引。索引条目作为表数据行的指针,使得查询能够很快的定位到所要查找的数据。所有的MySQL数据类型都可以创建索引。
WindWant
2020/09/11
1K0
MySQL索引入门简述
用来加快查询的技术很多,其中最重要的是索引。通常索引能够快速提高查询速度。如果不适用索引,MYSQL必须从第一条记录开始读完整个表,直到找出相关的行。表越大,花费的时间越多。但也不全是这样。本文讨论索引是什么,如何使用索引来改善性能,以及索引可能降低性能的情况。
wangxl
2018/07/27
1.1K0
MySQL统计信息更新小结
MySQL优化器的工作之一是选择索引。通过选择索引,找到一个最优的执行方案,以最小的代价去执行语句。而评估代价大小的因素之一,就是扫描行数。因为扫描的行数越少,访问磁盘数据的次数越少,消耗的CPU资源就相应越少。另外,优化器还会结合是否使用临时表、是否排序等因素进行综合判断。
胖五斤
2022/12/25
2.9K0
MySQL索引统计信息更新相关的参数
  1. innodb_stats_on_metadata(是否自动更新统计信息),MySQL 5.7中默认为关闭状态
星哥玩云
2022/08/17
1.5K0
MySQL索引统计信息更新相关的参数
推荐阅读
相关推荐
MySQL选错索引了怎么办?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验