【MySQL篇】持久化和非持久化统计信息的深度剖析(第一篇,总共六篇)
💫《博主介绍》:✨又是一天没白过,我是奈斯,DBA一名✨
💫《擅长领域》:✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux,也在扩展大数据方向的知识面✌️
💖💖💖大佬们都喜欢静静的看文章,并且也会默默的点赞收藏加关注💖💖💖
哈喽各位小伙伴,好久不见甚是想念。今天给大家上强度,讲解一下和SQL优化有关的内容——统计信息、优化器、执行计划、hint干预等。众所周知,优化器在SQL执行过程中扮演着至关重要的角色,它依赖于统计信息来为每个SQL语句制定最优的执行计划。而这些统计信息对于优化器的决策具有决定性的影响。因此,了解和掌握统计信息、优化器、执行计划、hint干预对于数据库的性能调优至关重要。接下来,我们将探讨统计信息、优化器、执行计划、hint干预的相关知识,帮助大家更好地理解并优化自己的数据库性能。
因为统计信息、优化器、执行计划、hint干预涉及到的内容过多,为了使大家更好消化,我将分成六篇文章来进行介绍,以便大家因为篇幅过长而感到阅读疲惫。六篇的内容分别如下,让大家先做了解:
- 第一篇:持久化和非持久化统计信息的深度剖析(当前篇)
- 第二篇:全面理解优化器和SQL语句的解析步骤
- 第三篇:SQL执行计划之访问路径
- 第四篇:SQL执行计划之多表连接
- 第五篇:精细化查询优化:如何有效使用Hint对优化器的执行计划进行干预
- 第六篇:SQL性能优化实战案例
目录
1.1 持久化统计信息(既innodb_stats_persistent=ON,默认on,生产必须持久化)
(1)相关参数
(2)配置每张表的统计信息参数
案例一:create表时配置表的持久化统计信息
(3)查看统计信息
(4)手动收集统计信息
4.1 analyze方式收集,oracle也支持(analyze是单表收集统计信息)
案例一:计算ANALYZE TABLE复杂性(消耗的读取)
4.2 mysqlcheck命令方式收集(mysqlcheck命令是全表全库收集统计信息)
(5)8.0版本直方图的最新变化
(6)解决统计信息差别较大的问题(执行计划受统计信息影响,统计信息不准会导致执行计划不准)
案例一:通过设置STATS_SAMPLE_PAGES或者设置innodb_stats_persistent_sample_pages解决统计信息不准问题
1.2 非持久化统计信息(既innodb_stats_persistent=OFF,默认on,不推荐使用仅了解)
(1)相关参数
(2)设置非持久化统计信息的两种方式
那让我们开始今天统计信息的介绍。
首先MySQL统计信息是指数据库通过采样、统计出来的表、索引的相关信息,例如:表的记录数、聚集索引page个数、字段Cardinality....。MySQL在生成执行计划时,需要根据索引的统计信息进行估算,计算出 最低代价 (或者说是最小开销)的执行计划。需要注意哦,MySQL支持有限的索引统计信息,因存储引擎不同而统计信息收集的方式也不同。而且MySQL官方关于统计信息的概念介绍几乎等同于无(官方文档的链接在下面,有兴趣的小伙伴可以看看),不过对于已经接触过其它类型数据库的小伙伴而言(比如oracle),理解这个概念应该不在话下。在oracle中统计信息是非常丰富的,在以后的篇幅中我也会介绍,今天还是主要介绍MySQL的。相对于其它数据库,MySQL统计信息无法手工删除,并且MySQL 8.0之前的版本是没有直方图的。optimizer优化器根据统计信息对每个sql语句执行最优的执行计划(执行计划受统计信息影响)。
MySQL统计信息的存储分为两种,非持久化和持久化统计信息。
官方文档对统计信息的介绍:
MySQL :: MySQL 8.0 Reference Manual :: 17.8.10 Configuring Optimizer Statistics for InnoDB
Oracle和MySQL统计信息的区别:
Oracle:统计信息是在特定的时间收集的全实例的,不是自动收集。当对象还没有统计信息时,那么先通过动态采样技术来选择执行计划,默认2级别的动态采样,采取对象的64个数据块进行分析。
MySQL:默认的持久化统计信息自动进行收集统计信息,但是需要注意MySQL InnoDB默认是以表为单位来收集和存储统计数据的。
1.1 持久化统计信息(既innodb_stats_persistent=ON,默认on,生产必须持久化)
持久化统计信息在数据库重启统计信息不丢失,统计信息会被持久化到物理表中,会给出最优的执行计划,稳定和精确,对于大表也节省了收集统计信息的所需资源。5.6.6开始默认使用了持久化统计信息。
持久化统计信息在以下情况会被自动更新:
1)innodb_stats_auto_recalc为on,自动更新统计信息。阈值是表中行数的10%发生更改。
2)create table、create index、alter table、truncate table等涉及数据修改的DDL语句
3)手动更新统计信息,注意执行过程中会加读锁:analyze table tablename。
4)dict_stats_thread线程专门处理统计信息。
5)而如果变更的行数超过16+n_rows/16(6.25%)或者表修改的行超过1/6或者20亿条时
(1)相关参数
一、innodb_stats_persistent
参数含义:是否启用持久化统计信息功能
默认值:ON
作用:变量控制统计信息是否持久化,统计信息在早期的MySQL中是不持久化,在新版本的MySQL中持久化统计信息是默认的选项。当变量打开时,统计信息就会被持久化到物理表中,统计信息会更加的稳定和精确,对于大表也节省了收集统计信息的所需资源。如果为off,可能会频繁地重新计算统计信息,这可能会导致查询执行计划的变化。
二、innodb_stats_auto_recalc
参数含义:是否自动触发更新统计信息
默认值:ON
触发阈值:表变化的数据是否超过10%,超过自动收集统计信息。
作用:InnoDB会长期追踪每一张表的行数,判断更新的记录是否超过表记录总数的1/10,超过那么就把这张表加入到后台的recalc pool中。由于自动统计信息重新计算(发生在后台)是异步,在运行影响超过10%的表的DML操作时(即innodb_stats_auto_recalc启用后),可能不会立即重新计算统计信息。在某些情况下,统计重新计算可能会延迟几秒钟(10s)。如果在更改表的重要部分之后立即需要最新统计信息,请运行ANALYZE TABLE以启动统计信息的同步(前台)重新计算。
如果禁用了innodb_stats_auto_recalc,请在对索引列进行实质性更改后,通过为每个适用的表发出ANALYZE TABLE语句来确保统计信息的准确性。
此设置适用于启用innodb_stats_persistent选项时创建的表。也可以在CREATE TABLE或者ALTER TABLE时通过STATS_AUTO_RECALC语法来指定比率。
三、innodb_stats_persistent_sample_pages
参数含义:持久化统计信息采样的索引页数。分析配置的页数,优化器根据统计信息给出执行计划
默认值:20
作用:在估计索引列的基数和其他统计信息(例如由ANALYZE TABLE计算的统计信息)时要采样的索引页数。增加该值可以提高索引统计的准确性,从而改进查询执行计划,但代价是在InnoDB表执行ANALYZE TABLE时增加I/O。
该值设置的越大,统计出的n_rows值越精确,但是统计耗时也就最久
该值设置的越小,统计出的n_rows值越不精确,但是统计耗时特别少。
1)统计信息不够准确,优化器选择次优计划:如果确定统计信息不够准确,则应增加innodb_stats_persistent_sample_pages的值,直到统计估计值足够准确。但是过多地增加innodb_stats_persistent_sample_pages可能会导致ANALYZE TABLE运行缓慢。
2)ANALYZE TABLE太慢:在这种情况下,应减少innodb_stats_persistent_sample_pages,直到ANALYZE TABLE执行时间可以接受。但是过多地降低该值可能会导致生成不准确的统计信息和执行计划的问题。
四、innodb_stats_include_delete_marked
默认值:OFF
作用:在5.7.16中引入的此参数,默认为不启用,表示在未提交的事务有从表中删除行,则InnoDB在收集统计信息时,将会排除这些delete_marked行。这可能会导致除READ UNCOMMITTED之外的事务隔离级别的事务,运行的不是最佳的执行计划。
为了避免这种情况,可以启用innodb_stats_include_delete_marked以确保在计算持久化统计信息时InnoDB包含Delete-marked记录。
(2)配置每张表的统计信息参数
innodb_stats_persistent、innodb_stats_auto_recalc和innodb_stats_persistent_sample_pages是全局配置选项。若要覆盖这些系统范围的设置并为各个表配置统计信息参数,可以在CREATE TABLE或ALTER TABLE语句中定义STATS_PERSISTENT、STATS_AUTO_RECALC和STATS_SAMPLE_PAGES子句。
一、STATS_PERSISTENT
含义:指定是否为InnoDB表启用持久统计信息。
设置值:
DEFAULT:表示表的持久统计信息设置由innodb_stats_persistent配置选项确定
1:表示启用表的持久统计信息
0:关闭此功能
二、STATS_AUTO_RECALC
含义:指定是否自动触发InnoDB表的持久统计信息。
设置值:
DEFAULT:表示表的持久统计信息设置由innodb_stats_auto_recalc配置选项确定
1:表示表中10%的数据发生更改时将重新计算统计信息
0:禁用自动重新计算此表
三、STATS_SAMPLE_PAGES
含义:指定在估计索引列的基数和其他统计信息(例如由ANALYZE TABLE计算的统计信息)时要采样的索引页数。
设置值:
DEFAULT:表示持久化统计信息采样的页数由innodb_stats_persistent_sample_pages配置选项确定
案例一:create表时配置表的持久化统计信息
CREATE TABLE't1`(
`id` int(8) NOT NULL auto increment,
data` varchar(255),
date` datetime,
PRIMARY KEY (`id`),
INDEX'DATE IX` (`date`)
) ENGINE=InnoDB,
STATS PERSISTENT=1,
STATS AUTO RECALC=1,
STATS SAMPLE PAGES=25;
(3)查看统计信息
table statistics相关视图:
mysql> select * from mysql.innodb_table_stats where table_name='表名';
database_name:数据库名
table_name:表名
last_update:统计信息最后一次更新时间,sql执行计划受统计信息影响。
n_rows:表的行数
clustered_index_size:聚集索引的页的数量
sum_of_other_index_sizes:其他索引的页的数量
mysql> select * from information_schema.tables where table_name='表名';
mysql> select * from information_schema.statistics where table_name='表名';
注意:mysql.innodb_table_stats会在持久化统计信息下自动更新,而information_schema.tables和information_schema.statistics不会自动更新需要手动执行analyze table或者mysqlcheck命令方式收集,所以统计信息以按照mysql.innodb_table_stats表的信息为准。
index statistics相关视图:
mysql> select * from mysql.innodb_index_stats where table_name='表名'; ---会在持久化统计信息下自动更新
database_name:数据库名
table_name:表名
index_name:索引名
last_update:统计信息最后一次更新时间,sql执行计划受统计信息影响。
stat_name:统计信息名
stat_value:统计信息的值
sample_size:采样大小
stat_description:类型说明
(4)手动收集统计信息
4.1 analyze方式收集,oracle也支持(analyze是单表收集统计信息)
innodb和myisam存储引擎都可以通过执行analyze table tablename来收集表和索引的统计信息。除非执行计划不准确,否则不要轻易执行该操作,如果是很大的表该操作会影响表的性能(单表9亿行的收集秒级完成,即使整个实例有2T,并且上千张表,通过mysqlcheck工具进行所有库的收集,也是几分钟就完成,亲测)
由于Analyze table会更新数据字典里的统计信息表(8.0)因此在innodb_read_only 开关被打开时有可能会导致执行失败。在analyze table的过程中会持有InnoDB表的read only锁,因此会存在短暂的阻塞用户写入更新删除的操作。除此之外analyze table要把table从table definition cache刷出来,因此还会需要一个flush lock,此时如果有长事务使用了这张表,那么必须等待长事务结束。
注意:ANALYZE、CHECK、OPTIMIZE、ALTER TABLE执行期间将对表进行锁定,因此一定注意要在数据库不繁忙的时候执行相关的操作。
5.7语法:
ANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ...
8.0语法(8.0中支持了直方图统计信息,因此analyze table还扩充了Histogram语法):
ANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ...ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]TABLE tbl_nameUPDATE HISTOGRAM ON col_name [, col_name] ...[WITH N BUCKETS]ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]TABLE tbl_nameDROP HISTOGRAM ON col_name [, col_name] ...
InnoDB表的ANALYZE TABLE复杂性(消耗的读取):
1)采样的页数,由innodb_stats_persistent_sample_pages定义。
2)表中索引列的数量(由多个数相加而成,参考下面案例)。
3)分区数量。如果表没有分区,则分区数被视为1。
总结:ANALYZE TABLE复杂性度=innodb_stats_persistent_sample_pages * 表中索引列的数量(多个数相加而成) * 分区数 * innodb_page_size
通常结果值越大,ANALYZE InnoDB TABLE的执行时间越长。
innodb_stats_persistent_sample_pages定义在全局级别采样的页数。要设置单个表的采样页数,请使用带有CREATE TABLE或ALTER TABLE的STATS_SAMPLE_PAGES选项。
如果innodb_stats_persistent = OFF,则采样的页数由innodb_stats_transient_sample_pages定义。
案例一:计算ANALYZE TABLE复杂性(消耗的读取)
ANALYZE TABLE复杂性度=innodb_stats_persistent_sample_pages * 表中索引列的数量(多个数相加而成) * 分区数 * innodb_page_size
O(n_sample
* (n_cols_in_uniq_i
+ n_cols_in_non_uniq_i
+ n_cols_in_pk * (1 + n_non_uniq_i))
* n_part * innodb_page_size)n_sample:是取样的页数(定义为innodb_stats_persistent_sample_pages)
n_cols_in_uniq_i:所有唯一索引中所有列的总数(不包括主键列)
n_cols_in_non_uniq_i:所有非唯一索引中所有列的总数
n_cols_in_pk:主键中的列数(如果没有定义主键,InnoDB在内部创建单列主键)
n_non_uniq_i:表中非唯一索引的数目
n_part:是分区的数量。如果没有定义分区,则该表被视为单个分区。
innodb_page_size:innodb每个页的大小是16K,且不可更改
SQL> CREATE TABLE t (a INT,b INT,c INT,d INT,e INT,f INT,g INT,h INT,PRIMARY KEY (a, b),UNIQUE KEY i1uniq (c, d),KEY i2nonuniq (e, f),KEY i3nonuniq (g, h)
);SQL> SELECT index_name, stat_name, stat_descriptionFROM mysql.innodb_index_stats WHEREdatabase_name='test' ANDtable_name='t' ANDstat_name like 'n_diff_pfx%';n_cols_in_uniq_i:所有唯一索引中不包括主键列的所有列的总数为2(c和d)
n_cols_in_non_uniq_i:所有非唯一索引中所有列的总数,为4(e,f,g和h)
n_cols_in_pk:主键中的列数为2(a和b)
n_non_uniq_i:表中非唯一索引的数量是2(i2nonuniq和i3nonuniq))
n_part:分区数,是1。
那么读取t表:
innodb_stats_persistent_sample_pages=20
n_cols_in_uniq_i =2
n_cols_in_non_uniq_i=4
n_cols_in_pk=2
n_non_uniq_i=2
n_part=1
innodb_page_size=16kb
估计表t读取20*(2+4+2*(1+2))*1*16kb=3840kb,为3.75M
4.2 mysqlcheck命令方式收集(mysqlcheck命令是全表全库收集统计信息)
mysqlcheck是用来检查、修复、优化、分析表。只有在数据库运行的状态下才可运行,意味着不用停止服务操作。
mysqlcheck其实就是CHECK TABLE(检查表), REPAIR TABLE(修复表), ANALYZE TABLE(分析表)以及OPTIMIZE TABLE(优化表)的便捷操作集合,利用指定参数将对于的SQL语句发送到数据库中进行执行。同样对于那些存储引擎的的支持,也受对于表维护SQL语句的限制(如check 则不支持MEMORY表, repair 则不支持 InnoDB表)
注意:ANALYZE、CHECK、OPTIMIZE、ALTER TABLE执行期间将对表进行锁定,因此一定注意要在数据库不繁忙的时候执行相关的操作。
mysqlcheck参数:
参数选项 | 描述 |
-A, --all-databases | 选择所有的库 |
-B, --databases | 选择多个库 |
-a, --analyze | 分析表ANALYZE TABLE |
-c, --check | 检查表CHECK TABLE |
-C, --check-only-changed | 最后一次检查之后变动的表CHECK TABLE |
-m, --medium-check | 近似完全检查,速度比--extended稍快CHECK TABLE |
-o, --optimize | 优化表OPTIMIZE TABLE |
--auto-repair | 自动修复表 |
-g, --check-upgrade | 检查表是否有版本变更,可用 auto-repair修复 |
-F, --fast | 只检查没有正常关闭的表 |
-f, --force | 忽悠错误,强制执行 |
-e, --extended | 表的百分百完全检查,速度缓慢 |
-q, --quick | 最快的检查方式,在repair 时使用该选项,则只会修复 index tree |
-r, --repair | 修复表REPAIR TABLE |
-s, --silent | 只打印错误信息 |
-V, --version | 显示版本 |
收集库所有表的统计信息:
收集test库:
[root@mgr1 ~]# mysqlcheck -uroot -p123456 -S /mysql/data/3306/mysql.sock --analyze --databases test
收集所有库:
[root@mgr1 ~]# mysqlcheck -uroot -p123456 -S /mysql/data/3306/mysql.sock --analyze --all-databases
SQL> select * from mysql.innodb_table_stats where database_name='test'; ---test库所有表的统计信息更新为最新
(5)8.0版本直方图的最新变化
MySQL 5.7并没有提供直方图的功能,某些情况下(如数据分布不均)仅仅更新统计信息不一定能得到准确的执行计划,只能通过index hint的方式指定索引。
在MySQL 8.0中支持了直方图统计信息,因此analyze table还扩充了Histogram语法,参考官方文档即可。
直方图是MySQL 8.0中新增的统计信息方式,Analyze table加上直方图语句就可以操作直方图的信息, 直方图并不是存储引擎层实现的,而是在Server层利用InnoDB存储引擎实现的系统表mysql.column_stats,MySQL利用JSON类型的字段来保存直方图的信息,其实现的核心代码在sql/histogram目录下。
直方图的具体的操作包括:更新直方图以及drop直方图,其中更新直方图还可以重新指定bucket的数目,需要注意的是直方图不支持加密表,不支持GIS列以及JSON列,以及不支持单列唯一索引的列。
通过histogram_generation_max_mem_size参数可以调整用于生成直方图的采样记录内存大小,通过查看information_schema的column_statistic表可以查看sampling-rate。
最新的MySQL8.0.19中,InnoDB实现了自己的采样算法,来避免全表扫描。在MySQL计算直方图填充时会调用Handler层的ha_sample_init, ha_sample_next以及ha_sample_end接口。在8.0.19前InnoDB并没有实现sample的接口,而是用的Handler层的默认实现rnd_next,也就是全表扫描,直到独到采样比率的数据为止。这里有一个问题,如果采样率设置为10%,那采样只是读前10%的记录。更科学的做法是在整棵索引树上均匀的采样。在新版本中终于有了InnoDB引擎层的sample实现。目前的代码只支持单线程的采样,但是从代码架构看已经实现了parallel_reader的接口,不久后一定会实现多线程并行的采样。InnoDB的采样是交给了单独的worker线程来实现的,一般是对主键进行。整体思路就是根据采样比率相对平均的选择叶子节点页面,假设采样率是10%,那么会选择一个叶子页面后跳过9个叶子页面,被选中的页面中会对所有的记录进行采样。
(6)解决统计信息差别较大的问题(执行计划受统计信息影响,统计信息不准会导致执行计划不准)
如果自动更新持久化统计信息后发现与实际count(*)数据量差距较大,可考虑增加表采样的数据页,两种方式修改:
修改一:全局变量(影响所有表)
innodb_stats_persistent_sample_pages默认20个页面。持久化统计信息采样的页数。分析配置的页数,优化器根据统计信息给出执行计划
缺点:过多地增加innodb_stats_persistent_sample_pages可能会导致ANALYZE TABLE运行缓慢。
该值设置的越大,统计出的n_rows值越精确,但是统计耗时也就最久
该值设置的越小,统计出的n_rows值越不精确,但是统计耗时特别少。
修改二:CREATE/ALTER表的参数(只影响设置的表)
ALTER TABLE TABLE_NAME STATS_SAMPLE_PAGES=40; ---经测试,此处STATS_SAMPLE_PAGES的最大值是65535,超出会报错。
STATS_SAMPLE_PAGES:指定在估计索引列的基数和其他统计信息(例如由ANALYZE TABLE计算的统计信息)时要采样的索引页数。表示持久化统计信息采样的页数由innodb_stats_persistent_sample_pages配置选项确定。
案例一:通过设置STATS_SAMPLE_PAGES或者设置innodb_stats_persistent_sample_pages解决统计信息不准问题
1)创建表
SQL> create table tb_700w like tb;
SQL> insert into tb_700w select * from tb limit 7000000;SQL> select * from mysql.innodb_table_stats where table_name='tb_700w';
---tb_700w真实有700万行数据,由于innodb_stats_persistent_sample_pages进行自动持久化统计信息采样只采集20页,那么就会有误差
2)设置STATS_SAMPLE_PAGES:
SQL> ALTER TABLE tb_700w STATS_SAMPLE_PAGES=65535; ---此处STATS_SAMPLE_PAGES的最大值是65535,超出会报错。
SQL> analyze table tb_700w;SQL> select * from mysql.innodb_table_stats where table_name='tb_700w';
---收集单表的STATS_SAMPLE_PAGES的最大值是65535个页,超出会报错。65535页还是不能给出准确的行数
3)设置innodb_stats_persistent_sample_pages:
注意:ANALYZE TABLE复杂性度=innodb_stats_persistent_sample_pages * 表中索引列的数量(多个数相加而成) * 分区数 * innodb_page_size,那么过多地增加innodb_stats_persistent_sample_pages,ANALYZE InnoDB TABLE的执行时间越长。
SQL> ALTER TABLE tb_700w STATS_SAMPLE_PAGES=default; ---恢复默认STATS_SAMPLE_PAGES,由innodb_stats_persistent_sample_pages配置选项确定
SQL> show variables like 'innodb_stats_persistent_sample_pages'; ---默认采集20页
算出innodb_stats_persistent_sample_pages最合适的值。公式:innodb_stats_persistent_sample_pages=ANALYZE TABLE复杂性度(大小)/表中索引列的数量(多个数相加而成)/分区数/innodb_page_size
SQL> show create table tb_700w\G;SQL> SELECT index_name, stat_name, stat_descriptionFROM mysql.innodb_index_stats WHEREdatabase_name='test' ANDtable_name='tb_700w' ANDstat_name like 'n_diff_pfx%';
详细算法参考上面(4)手动收集统计信息的案例一:计算ANALYZE TABLE复杂性(消耗的读取)
n_cols_in_uniq_i:所有唯一索引中不包括主键列的所有列的总数为0
n_cols_in_non_uniq_i:所有非唯一索引中所有列的总数,为0
n_cols_in_pk:主键中的列数为1(id)
n_non_uniq_i:表中非唯一索引的数量是0
n_part:分区数,是1。
那么读取tb_700w表:
n_cols_in_uniq_i =0
n_cols_in_non_uniq_i=0
n_cols_in_pk=1
n_non_uniq_i=0
n_part=1
innodb_page_size=16kb
innodb_stats_persistent_sample_pages=(1611Mx1024)/(0+0+1*(1+0))/1/16kb=103104
SQL> set global innodb_stats_persistent_sample_pages=103104;
SQL> analyze table tb_700w;SQL> select * from mysql.innodb_table_stats where table_name='tb_700w'; 给出了最准确的统计信息
1.2 非持久化统计信息(既innodb_stats_persistent=OFF,默认on,不推荐使用仅了解)
非持久化统计信息存储在内存里,如果数据库重启统计信息将丢失,在下一次访问表时重新计算。会导致频繁地重新计算统计信息,这可能会导致查询执行计划的变化。不推荐使用也不是默认值。
当innodb_stats_persistent = OFF或使用STATS_PERSISTENT = 0创建或更改单张表时,统计信息不会保留到磁盘。相反统计信息存储在内存中,并在服务器关闭时丢失。某些业务和某些条件下也会定期更新统计数据。
非持久化统计信息在以下情况会被自动更新(前提innodb_stats_on_metadata设置为on,默认off):
1)手动更新统计信息,注意执行过程中会加读锁:analyze table tablename
2)设置innodb_stats_on_metadata=ON(默认off),执行SHOW TABLE STATUS , SHOW INDEX,查询INFORMATION_SCHEMA下的TABLES, STATISTICS
3)启用--auto-rehash选项,这是默认设置。--auto-rehash选项会打开所有InnoDB表,打开表的操作会导致统计数据重新计算。使用mysql client登录。
4)表第一次被打开
5)距上一次更新统计信息,表1/16的数据被修改
总结:非持久化统计信息的缺点显而易见,数据库重启后如果大量表开始更新统计信息,会对实例造成很大影响,所以目前都会使用持久化统计信息。
(1)相关参数
一、innodb_stats_on_metadata
参数含义:表示是否InnoDB在(如SHOW TABLE STATUS)或访问INFORMATION_SCHEMA.TABLES或INFORMATION_SCHEMA.STATISTICS)操作期间更新统计信息。
默认值:OFF
作用:保留禁用的设置可以提高具有大量表或索引的模式的访问速度。它还可以提高涉及InnoDB表的查询的执行计划的稳定性。
此选项仅在优化器统计信息配置为非持久性时适用。当innodb_stats_persistent为off(默认on,启用持久化统计信息)时生效。或者使用STATS_PERSISTENT=0创建或修改单个表时,优化器统计信息不会被持久化到磁盘。在关闭持久化统计信息时,是否在show table status/查看information_schema的TABLES,STATISTICS表时更新统计信息(亲测关闭innodb_stats_persistent=off,在设置innodb_stats_on_metadata为on或者off下都使用show table status/查看information_schema的TABLES、STATISTICS表也不会更新统计信息,了解即可,生产环境必须开启持久化统计信息也是默认选项)
二、innodb_stats_transient_sample_pages
参数含义:表示每次随机采样页的数量
默认值:8
作用:当innodb_stats_persistent = 0时,innodb_stats_transient_sample_pages的值会影响所有InnoDB表和索引的索引采样。更改索引样本大小时,请注意以下潜在的重大影响:
像1或2这样的小值可能导致基数估计不准确。
增加innodb_stats_transient_sample_pages值可能需要更多磁盘读取。远大于8(例如100)的值可能导致打开表或执行SHOW TABLE STATUS所花费的时间显着减慢。优化器可能会根据索引选择性的不同估计选择非常不同的查询计划。
(2)设置非持久化统计信息的两种方式
1)全局变量(影响所有表)
innodb_stats_persistent=OFF ---默认on,启用持久化统计信息。变量控制统计信息是否持久化,统计信息在早期的MySQL中是不持久化,在新版本的MySQL中持久化统计信息是默认的选项。当变量打开时,统计信息就会被持久化到物理表中,统计信息会更加的稳定和精确,对于大表也节省了收集统计信息的所需资源。如果为off,可能会频繁地重新计算统计信息,这可能会导致查询执行计划的变化。
2)CREATE/ALTER表的参数(只影响设置的表)
STATS_PERSISTENT=0 ---是否启用InnoDB表的持久统计功能。 默认值由innodb_stats_persistent配置选项决定。 值1启用表的持久统计,而值0关闭此特性。 在通过CREATE TABLE或ALTER TABLE语句启用持久统计信息后,在将代表性数据加载到表中之后,发出ANALYZE TABLE语句来计算统计信息。
STATS_PERSISTENT:指定是否为InnoDB表启用持久统计信息。默认值由innodb_stats_persistent配置选项确定。1:表示启用表的持久统计信息; 0:关闭此功能
相关文章:
【MySQL篇】持久化和非持久化统计信息的深度剖析(第一篇,总共六篇)
💫《博主介绍》:✨又是一天没白过,我是奈斯,DBA一名✨ 💫《擅长领域》:✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux,也在扩展大数据方向的知识面✌️…...
Ubuntu下安装Qt
1.如图1所示,在Index of /archive上下载安装包; 图1 2.将图1安装包下载好之后,通过共享文件夹的方式拷贝到ubutntu,如图2所示; 图2 3.如图3所示,执行chmod x qt-creator-opensource-linux-x86_64-10.0.2.…...
丹摩征文活动 | AI创新之路,DAMODEL助你一臂之力GPU
目录 前言—— DAMODEL(丹摩智算) 算力服务 直观的感受算力提供商的强大 平台功能介绍 镜像选择 云磁盘创建 总结 前言—— 只需轻点鼠标,开发者便可拥有属于自己的AI计算王国 - 从丰富的GPU实例选择,到高性能的云磁盘,再到预配置的深度学习…...
数据库(总结自小林coding)|索引失效的场景、慢查询、原因及如何优化?undo log、redo log、binlog 作用、MySQL和Redis的区别
数据库(总结自小林coding)|索引失效的场景、慢查询、原因及如何优化?undo log、redo log、binlog 作用、MySQL和Redis的区别 说一下索引失效的场景?什么是慢查询?原因是什么?可以怎么优化?undo …...
Docker容器运行CentOS镜像,执行yum命令提示“Failed to set locale, defaulting to C.UTF-8”
最近对运维比较感兴趣,以前虽然对公司负责的项目做过运维工作,但用的都是最原始的方法,例如是在阿里云服务器上直接安装jdk,tomcat,redis ,nginx 。这种方式对不大的项目还能够支持,随着项目变大,服务增加&…...
OpenCV基本图像处理操作(六)——直方图与模版匹配
直方图 cv2.calcHist(images,channels,mask,histSize,ranges) images: 原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如[img]channels: 同样用中括号括来它会告函数我们统幅图 像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的…...
【LLM学习笔记】第四篇:模型压缩方法——量化、剪枝、蒸馏、分解
文章目录 1. 为什么要进行模型压缩2. 模型量化2.1 常见数据类型2.2 浮点数表示2.3 线性量化2.4 非线性量化2.5 挑战2.6 实际应用 3. 模型剪枝4. 模型蒸馏4.1 模型蒸馏的基本流程4.2 模型蒸馏的优势4.3 实际应用 5. 低秩分解(低秩近似)5.1 基本概念5.2 实…...
python3 自动更新的缓存类
这个类会在后台自动更新缓存数据,你只需要调用方法来获取数据即可。 自动更新缓存类 以下是 AutoUpdatingCache 类的实现: import threading import timeclass AutoUpdatingCache:def __init__(self, update_function, expiry_time60):""&qu…...
英语知识网站开发:Spring Boot框架应用
3系统分析 3.1可行性分析 通过对本英语知识应用网站实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本英语知识应用网站采用SSM框架,JAVA作为开发语…...
文件上传upload-labs-docker通关
(图片加载不出,说明被和谐了) 项目一: sqlsec/ggctf-upload - Docker Image | Docker Hub 学习过程中,可以对照源码进行白盒分析. 补充:环境搭建在Linux虚拟机上的同时,以另一台Windows虚拟机进行测试最…...
git(Linux)
1.git 三板斧 基本准备工作: 把远端仓库拉拉取到本地了 .git --> 本地仓库 git在提交的时候,只会提交变化的部分 就可以在当前目录下新增代码了 test.c 并没有被仓库管理起来 怎么添加? 1.1 git add test.c 也不算完全添加到仓库里面&…...
Doris实战—构建日志存储与分析平台
构建日志存储与分析平台 日志是系统运行的详细记录,包含各种事件发生的主体、时间、位置、内容等关键信息。出于运维可观测、网络安全监控及业务分析等多重需求,企业通常需要将分散的日志采集起来,进行集中存储、查询和分析,以进一步从日志数据里挖掘出有价值的内容。 针…...
【vue3+Typescript】unapp+stompsj模式下替代plus-websocket的封装模块
由于plus-websocket实测存在消息丢失的问题,只能寻找替代的方案,看文章说使用原生的即可很好的工作。而目前在stompjs里需要使用websocket类型的封装模块,看了下原来提供的接口,采用uniapp原生的websocket模式,对原模块…...
Tcon技术和Tconless技术介绍
文章目录 TCON技术(传统时序控制器)定义:主要功能:优点:缺点: TCONless技术(无独立时序控制器)定义:工作原理:优点:缺点: TCON与TCONl…...
C#-利用反射自动绑定请求标志类和具体执行命令类
文章速览 概述例程请求类命名空间父类示例子类示例 命令类命名空间子类示例 记录的数据结构实现绑定方法 坚持记录实属不易,希望友善多金的码友能够随手点一个赞。 共同创建氛围更加良好的开发者社区! 谢谢~ 概述 需求: 将指定的两种类型的…...
高中数学练习:初探均值换元法
文章目录 1. 均值换元法定义2. 均值换元法优点3. 均值换元法应用4. 均值换元法示例4.1 求解分式方程4.2 求解指数方程4.3 计算最大值 5. 实战小结 1. 均值换元法定义 均值换元法是一种数学技巧,通过引入新变量 t t t将两个变量 x x x和 y y y表示为它们的平均值加上…...
数据结构单链表,顺序表,广义表,多重链表,堆栈的学习
单链表 比如一个多项式,主要包括x的系数,x的指数,那么可以创建一个一维数组来存储它的系数和指数,用数组下标来表示。它的系数可以用数组下标对应的数组元素来储存。 可是这样储存会浪费空间所以采用单链表形式来存储。 即创建一…...
【保姆级教程】使用lora微调LLM并在truthfulQA数据集评估(Part 2.在truthfulQA上评估LLM)
上一期我们成功用lora微调了一个模型传送门,怎样评估模型呢?目前LLM没有一个统一的BENCHMARK。我们今天选用truthfulQA。 truthfulQA数据集格式如下所示 {question: What is the smallest country in the world that is at least one square mile in ar…...
thinkphp中对请求封装
请求的封装 //调用 $res Http::post($this->baseUrl . $url,$params,[CURLOPT_HTTPHEADER > [Content-Type: application/json,Content-Length: . strlen($params),],]);<?php namespace fast; /*** 字符串类*/ class Http {/*** 发送一个POST请求*/public static …...
leetcode hot100【LeetCode 215.数组中的第K个最大元素】java实现
LeetCode 215.数组中的第K个最大元素 题目描述 给定一个整数数组 nums 和一个整数 k,请返回数组中第 k 个最大的元素。 请注意,要求排名是从大到小的,因此第 k 个最大元素是排序后的第 k 个元素。你需要设计一个高效的算法来解决这个问题。…...
簡單易懂:如何在Windows系統中修改IP地址?
無論是為了連接到一個新的網路,還是為了解決網路連接問題,修改IP地址都是一個常見的操作。本文將詳細介紹如何在Windows系統中修改IP地址,包括靜態IP地址的設置和動態IP地址的獲取。 IP地址是什麼? IP地址是互聯網協議地址的簡稱…...
Python中的23种设计模式:详细分类与总结
设计模式是解决特定问题的通用方法,分为创建型模式、结构型模式和行为型模式三大类。以下是对每种模式的详细介绍,包括其核心思想、应用场景和优缺点。 一、创建型模式(Creational Patterns) 创建型模式关注对象的创建࿰…...
日历使用及汉化——fullcalendar前端
官网 FullCalendar - JavaScript Event Calendar 引入项目 <link hrefhttps://cdnjs.cloudflare.com/ajax/libs/fullcalendar/5.10.1/main.min.css relstylesheet /><script srchttps://cdnjs.cloudflare.com/ajax/libs/fullcalendar/5.10.1/main.min.js></sc…...
视频截断,使用 FFmpeg
使用 FFmpeg 截取视频并去掉 5 分 49 秒后的内容,可以使用以下命令: ffmpeg -i input.mp4 -t 00:05:49 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 192k output.mp4-i input.mp4: 指定输入视频文件 input.mp4。 -t 00:05:49&#x…...
使用系统内NCCL环境重新编译Pytorch
intro: 费了老大劲,来重新编译pytorch,中间报了无数错误。原生的编译好的pytorch是直接用的其自带NCCL库,并且从外部是不能进行插桩的,因为根本找不到libnccl.so文件。下面记录下重新编译pytorch的过程。指定USE_SYSTEM_NCCL1。这…...
1. Klipper从安装到运行
本文记录Klipper固件从安装,配置到运行的详细过程 Klipper是3D打印机固件之一,它通常运行在linux系统(常使用Debian,其它的linux版本也可以)上,因此需要一个能运行Linux系统的硬件,比如电脑&am…...
docker 卸载与安装
卸载 查询之前安装的docker, 没有查到则不用卸载删除 yum list installed | grep docker 卸载安装包 yum remove docker-* -y 删除镜像、容器、默认挂载卷 rm -rf /var/lib/docker 安装 -ce 安装稳定版本 -y 当安装过程提示选择全部为 "yes" yum install d…...
跨部门文件共享安全:平衡协作与风险的关键策略
在现代企业中,跨部门协作已成为推动业务发展的关键因素。然而,随着信息的自由流动和共享,文件安全风险也随之增加。如何在促进跨部门协作的同时,确保文件共享的安全性,成为了一个亟待解决的问题。 一、明确文件分类与…...
基于单片机的智慧小区人脸识别门禁系统
本设计基于单片机的智慧小区人脸识别门禁系统。由STM32F103C8T6单片机核心板、显示模块、摄像头模块、舵机模块、按键模块和电源模块组成。可以通过摄像头模块对进入人员人脸数据进行采集,识别成功后,舵机模块动作,模拟门禁打开,门…...
【es6】原生js在页面上画矩形及删除的实现方法
画一个矩形,可以选中高亮,删除自己效果的实现,后期会丰富下细节,拖动及拖动调整矩形大小 实现效果 代码实现 class Draw {constructor() {this.x 0this.y 0this.disX 0this.disY 0this.startX 0this.startY 0this.mouseDo…...
武汉网站设计武/石家庄最新消息
Java 是当今最流行的编程语言之一,常年位居最受欢迎编程语言排行榜前三。一个优秀的java程序员,在研发时离不开对测试框架的了解,从而开发出更安全和更高效的代码。使用这些测试框架的其中一个最重要的原因是减少出错的可能性,提高…...
table做网站/网站推广优化方案
在filter中经常会遇到>begindate这样的例子 而最终导致和日期提示控件之间相互比较的时候报错,日期格式类错误 于是做了如下的操作,再次用新的参数添加过滤器,一切正常。神奇的mysql. 第一步: cast([日期],varchar(8)) 第二步&…...
武汉做医院网站公司电话/网站排名优化方案
为什么选择WijmoJS? 作为一款纯前端控件集,WijmoJS秉承“快如闪电,触控优先”的设计理念,在提供优质服务和产品的同时,专注于企业应用开发,不断优化产品架构,与时俱进。除在全球率先支持Angular…...
网站注册信息查询/旺道网站排名优化
#!/bin/bashecho -n Count:tput sccount0while true;doif [ $count -lt 40 ];thenlet count;sleep 1;tput rctput edecho -n $count;elseexit 0;fidone使用Shell实现一个倒计时, 其中,tput sc 是存储光标位置, tput rc 是恢复光标位置 tput …...
苏州模板建站定制/近三天时政热点
在Vmware workstation 9中装了个Linux mint 15试试效果,居然不支持1600x900的分辨率,现在14寸的高分都是这分辨率了。上网搜了搜,把以下代码放到shell文件里能改变分辨率,设成1600x900.Mint15-Mate Xsession.d # cat /usr/local/b…...
湛江电气建站软件/百度入口网页版
默认情况下,Graphics 绘图类使用的笔画属性是粗细为1个像素的正方形,而Java2D的Graphics2D类可以调用setStroke()方法设置笔画的属性,如改变线条的粗细、虚实和定义线段端点的形状、风格等。语法如下:setStroke(Stroke stroke)其中…...