美文网首页程序员
「Mysql索引原理(十六)」维护索引和表-更新索引统计信息

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

作者: 源码之路 | 来源:发表于2020-06-20 18:50 被阅读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)。例如
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来手动更新。否则,索引统计信息就会永远不变。如果数据分布发生大的变,可能会出现一些很糟糕的执行计划。

相关文章

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

    MySQL的査询优化器会通过两个API来了解存储引擎的索引值的分布信息,以决定如何使用索引。第一个API是 ...

  • Mysql 相关

    MySQL索引 MySQL索引背后的数据结构及算法原理 覆盖索引和回表操作 MySQL性能优化 MySql表分区详...

  • MySQL索引及查询优化书目录

    MySQL索引的原理之索引目的 MySQL索引的原理之索引原理 MySQL索引的原理之索引的类型 MySQL索引的...

  • 避免回表与覆盖索引

    为什么要避免回表 mysql维护着两种索引树:聚集索引、非聚集索引。我们建立的索引都属于非聚集索引。通过非聚集索引...

  • MySQL数据库基础之索引技术及字段维护

    MySQL索引和字段修改 1、MySQL索引技术 ①、创建带索引的表 Create table表名(user)( ...

  • 索引

    MySQL索引原理及慢查询优化 索引的储存分类: BTREE索引和HASH索引。MyISAM 和 InnoDB 存...

  • MySQL索引

    MySQL索引 索引介绍 索引原理与分析 组合索引 索引失效分析 索引介绍 什么是索引索引:包括聚集索引、覆盖索引...

  • Mysql 索引原理及优化

    Mysql 索引原理及优化 什么是索引 为什么需要索引? 索引是数据表种一个或者多个列进行排序的数据结构 索引能够...

  • MySQL优化系列7-MySQL的统计信息

    一.InnoDB的统计信息概述 MySQL统计信息是指 数据库通过采样、统计出来的表、索引的相关信息,例如,表的记...

  • MySQL 索引

    MySQL 索引 数据库索引的原理:数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表...

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/gtygxktx.html