MySQL innodb统计信息

对innodb 统计信息的控制可以通过如下几个常用的variables 来实现

1、innodb_stats_persistent:

  这个参数控制着innodb的统计信息是否持久化到磁盘,先说明一下持久化到磁盘是什么意思;通常来说统计信息只保存在内存中,也就是说如果mysql服务一重启那么之前

  所有的统计信息都没有了,这个情况下mysql就要重新收集&计算了;如果统计信息持久化到磁盘了,那么就可以直接从磁盘中读取;

  为了真正的可以达到红统计信息持久化到磁盘光是innodb_stats_persistent=on是做不到的;innodb_stats_persistent=on 只是说明了打开了mysql把表的统计

  信息持久化到磁盘的能力,但是这个能力用不用不是由表自己说了算;在create table 语句中指定STATS_PERSISTENT=1这个时候表就支持持久化工能了。

  create table t(x int,y int) STATS_PERSISTENT=1;

2、由1中的描述可知 innodb的表可以分成两大类、一类是支持持久化的表,一类是不支持持久化的表;它们各自的统计信息的收集方式又可以通过不同的变量来控制

3、innodb_stats_persistent_sample_pages 持久化统计信息的采样页

4、innodb_stats_transient_sample_pages 非持久化统计信息的采样页

5、innodb_stats_auto_recalc 变更超过10%的时候要不要自动收集统计信息

6、innodb_stats_on_metadata 执行show table status | information_schema.tables 时是否自动收集统计信息

7. 我们将一条查询SQL提交给MySQL之后,MySQL在进行真正的查询操作之前通常会经历两个阶段:SQL解析和查询优化。在SQL解析过程中,MySQL会将SQL解析为一个树状结构,而在查询优化阶段,MySQL会决定以什么方式进行查询,那么MySQL以什么方式进行查询的抉择依据是什么呢?答案就是这篇文章要介绍的MySQL统计信息,因为我厂的MySQL实际使用的是Percona分支,因此本文相关的实验知识是基于Percona分支的。

带着问题

  • MySQL统计的信息包括什么内容?是用来做什么的?
  • MySQL统计信息基于表和索引,表和索引是要变化的,那么MySQL是如何保证数据的时效性的?
  • MySQL的统计机制有什么问题?统计策略如何选择?

MySQL统计信息

持久化存储->
对于InnoDB存储引起来说,统计信息分别存储在mysql库的下面两张表中:

  • innodb_table_stats
  • innodb_index_stats

innodb_table_stats存储表维度的统计信息,innodb_index_stats存储索引维度的统计信息。在持久化存储的情况下,当设置为自动更新统计信息的时候且表中有超过10%的数据被更新的时候会执行统计信息的重新计算,而且重新统计不是立即执行的,而是等了一段时间,这个值在MySQL中被定义为MIN_RECAL_INTERVAL=10(秒)。

易失性存储->

当innodb_stats_persistent=OFF的时候,MySQL统计信息存储在内存之后,很显然当重启数据库的时候,这些信息会丢失。

在易失性存储的情况下,统计信息重新计算的时机和持久化存储方式是不同的,我们来看看哪些条件会触发该情况下统计信息的重新计算:

  • 执行ANALYZE TABLE命令
  • 执行如下命令:SHOW TABLE STATUS, SHOW INDEX。
  • 在innodb_stats_on_metadata选项开启的情况下查询INFORMATION_SCHEMA.TABLES表或INFORMATION_SCHEMA.STATISTICS表
  • 通过--auto-rehash参数开启客户端连接,--auto-rehash参数导致InnoDB表被打开,InnoDB表被打开导致统计信息被重新计算
  • 表被第一次打开
  • 距离上次统计之后,表的1/16的数据被更新

了解在什么方式下统计信息会被重新计算对于数据库的使用优化是有帮助的,比如我们可以破坏一些条件而让事情向着对我们有力的一面发展。

统计内容:
MySQL统计信息包括哪些内容呢?MySQL分别从表维度和索引维度构建统计信息。

表统计信息:
innodb_table_stats表存储的是表维度的统计信息,innodb_table_stats表有6个字段,他们的各字段相关定义以及含义如下表所示:

字段名 字段类型 字段含义
database_name    verchar(64)    统计信息所属表的数据库名
table_name    verchar(64)    统计信息所属的表名
last_update    timestamp    统计信息最后一次更新的时间
n_rows    bigint(20) unsigned    表所包含的行数
clustered_index_size    bigint(20) unsigned    聚集索引的页的数量
sum_of_other_index_size    bigint(20) unsigned    其他索引所占的页的数量

我找了一张我们现存的表测试一下:

如上图所示,CL_CommunityNavStatInfo表当前的记录数为5281。

上面我们看到表中实际有5281行数据,但是统计出来的是5228行数据,这是因为什么呢?这个问题留在精度问题部分进行讨论。

索引统计信息
innidb_index_stats表存储的是索引维度的统计信息,innodb_index_stats表有8个字段,他们的各字段相关定义以及含义如下表所示:

字段名  字段类型  字段含义
database_name    varchar(64)    统计信息所属表的数据库名
table_name    varchar(64)    统计信息所属表名
index_name    varchar(64)    统计信息所属索引名
last_update    timestamp    统计信息更新的时间
stat_name    varchar(64)    统计信息名称
stat_value    bigint(20) unsigned    统计值
sample_size    bigint(20) unsigned    采样大小
stat_description    varchar(64)    统计描述信息

我们依然使用上面测试用到的CL_CommunityNavStatInfo表进行测试,先看看CL_CommunityNavStatInfo表的索引定义:

CL_CommunityNavStatInfo表建立了三个索引,我们通过innodb_index_stats表来看看这三个索引的统计信息:

上图为表CL_CommunityNavStatInfo所有索引的统计信息,比如最后一行,size代表主键聚集所以所占页数大小为161,叶子节点所占空大小为128页,id的区分度为5228,这个数字其实也是统计的表的行数,sample_size为20表示采样页数。

精度问题
采样大小

上面提到了sample_size这个数字,其实MySQL的统计数据是基于采样数据估算的,而采样的大小是用户可控的,默认值为20,我们可以通过修改采样大小来控制统计信息的精确性,同时这也会影响性能。比如我们用下面命令将采样大小调整为200:

SET global innodb_stats_persistent_sample_pages=200;
200是我们随表挑的一个大于所有数据页数的数字,这样保证统计信息基于全量数据统计,通过ANALYZE TABLE CL_CommunityNavStatInfo;命令重新统计之后,再来看看统计信息:

是不是无比的准确?再继续看看索引的统计信息:

现在的统计信息已经是基于全量的数据统计了,虽然数据准确了,但是我们同时也损失了一部分的性能。

统计时机

定时轮训

统计时机关心的是什么时候进行统计信息的更新。innodb_stats_auto_recalc参数用于控制是否让MySQL自行在需要的时候更新统计信息,当它的值为ON的时候,统计信息的重新计算是异步的,MySQL有一个线程专门用来做这个事情,这个线程每隔10秒钟回去看看要不要进行统计,否则我们需要使用ANALYZE TABLE命令来保证统计信息的时效性。那么我们是选择将统计信息的更新权利完全霸占还是将其授权给MySQL让它自行更新呢?这个问题留给读者思考。

总结

本文分别从MySQL统计信息的存储、内容、精度和统计时机方面对MySQL统计信息进行了一定的学习,了解了MySQL统计信息的相关知识,我认为我们至少可以解决一些实际问题了。比如:

我们当前应用的数据源MySQL关于统计方面的配置有没有问题?
我们是否可以试着通过调整采样大小来控制统计信息的精确度?从而影响SQL优化器的决策?
我们是否可以通过统计信息来估算表中数据所占用的存储空间?
……
等等。

原文地址:https://www.cnblogs.com/DataArt/p/10350851.html

时间: 2024-10-10 16:12:09

MySQL innodb统计信息的相关文章

MySQL的统计信息学习总结

原文:MySQL的统计信息学习总结 统计信息概念 MySQL统计信息是指数据库通过采样.统计出来的表.索引的相关信息,例如,表的记录数.聚集索引page个数.字段的Cardinality.....MySQL在生成执行计划时,需要根据索引的统计信息进行估算,计算出最低代价(或者说是最小开销)的执行计划.MySQL支持有限的索引统计信息,因存储引擎不同而统计信息收集的方式也不同. MySQL官方关于统计信息的概念介绍几乎等同于无,不过对于已经接触过其它类型数据库的同学而言,理解这个概念应该不在话下.

MySQL索引统计信息更新相关的参数

MySQL统计信息相关的参数: 1. innodb_stats_on_metadata(是否自动更新统计信息),MySQL 5.7中默认为关闭状态 仅在统计信息配置为非持久化的时候生效. 也就是说在innodb_stats_persistent 配置为OFF的时候,非持久化存储统计信息的手,innodb_stats_on_metadata的设置才生效. 当innodb_stats_on_metadata设置为ON的时候, InnoDB在执show table status 或者访问INFORMA

Atitit mysql数据库统计信息

SELECT table_name, table_rows, index_length, data_length, auto_increment, create_time, update_time, table_collation, ENGINE FROM INFORMATION_SCHEMA. TABLES WHERE table_schema = 'yunprint' 作者:: 绰号:老哇的爪子claw of Eagle 偶像破坏者Iconoclast image-smasher 捕鸟王"B

Oracle Mysql 统计信息

我们知道Oracle的统计信息将严重影响CBO对执行计划的选择,针对不同大小的表制定收集规则并且定期执行是非常重要的.Oracle通过如下脚本即可收集统计信息: BEGIN DBMS_STATS.GATHER_TABLE_STATS(ownname =>'ZBDBA', tabname =>'TEST', estimate_percent =>30, method_opt =>'for all columns size repeat', no_invalidate =>FAL

MySQL 5.6为什么关闭元数据统计信息自动更新&统计信息收集源代码探索

问题描述: MySQL 5.5.15 原sql如下: select constraint_schema,table_name,constraint_name,constraint_type from information_schema.table_constraints where table_schema not in ('information_schema', 'mysql', 'test','performance_schema'); 不只是上面提到的table_constraints

MySQL 8.0 中统计信息直方图的尝试

直方图是表上某个字段在按照一定百分比和规律采样后的数据分布的一种描述,最重要的作用之一就是根据查询条件,预估符合条件的数据量,为sql执行计划的生成提供重要的依据. 在MySQL 8.0之前的版本中,MySQL仅有一个简单的统计信息却没有直方图,没有直方图的统计信息可以说是没有任何意义的. MySQL 8.0新特性之一就是开始支持统计信息的直方图,这个概念很早就提出来了,抽空具体尝试了一下使用方法. 之前写过MSSQL相关统计信息的一点东西,在原理上都是一致的, 照旧,直接上例子,造数据,创建一

mysql-5.7 持久化统计信息详解

一.持久化统计信息的意义: 统计信息用于指导mysql生成执行计划,执行计划的准确与否直接影响到SQL的执行效率:如果mysql一重启 之前的统计信息就没有了,那么当SQL语句来临时,那么mysql就要收集统计信息然后再生成SQL语句的执行 计划.如果能在关闭mysql的时候就把统计信息保存起来,那么在启动时就不要再收集一次了,这种处理方式 有助于效率的提升. 二.统计信息准确与否也同样重要: 第一目中我们说明了"持久化统计信息的意义",我们的假设统计信息是有用的,是准确的:如果统计信

MySQL -- innodb中cardinality是如何统计的

cardinality是放在mysql存储引擎层进行的.采用的是采样取值.在innodb存储引擎中,cardinality统计信息的更新发生在两个操作中:insert和update 更新策略为:-表中1/16的数据发生过变化-stat_modified_counter>2000 000 000 (stat_modified_counter是innodb存储引擎中的一个计数器) 默认Innodb存储引擎对8个叶子节点进行采样.受参数innodb_stats_sample_pages影响. 当执行语

InnoDB的统计信息表

MySQL中的InnoDB统计相关说明: 参考:https://www.jianshu.com/p/0b8d2f9cee7b 其他参考:https://www.cnblogs.com/sunss/p/6110383.html 叶总的相关推文:https://mp.weixin.qq.com/s/1MsyxhtG6Zk3Q9gIV2QVbA itdks董爷的分享:http://www.itdks.com/eventlist/detail/1161 下面的介绍都是以MySQL社区版5.7为例. my