怀抱观古今,寝食展戏谑。这篇文章主要讲述MYSQL 8 统计信息持久化 与 null相关的知识,希望能为你提供帮助。
在任何数据库中统计信息是帮助数据库查询中走更适合的查询路径的基础,mysql 8 中持久化的统计信息怎么做,怎么能持久化后提高执行计划的稳定性。
默认的情况下,这个参数是打开的
show variables like innodb_stats_persistent;
实际当中统计信息是存在于mysql.innodb_table_stats
and
mysql.innodb_index_stats 这两个表中的
具体每个表变化多少数据量才开始进行统计,要看 innodb_stats_auto_recalc 这个参数,默认打开,并且一个表中的10%的行进行变化了,才开始统计信息的重新计算。
实际上下面的某些东西可能和有些开源数据库有类似的地方了,可以调整的参数是在表的层面还是数据库层面,都可以细微的调整了,因为我们不能让每个表的数据的增量都一致,假象一个表一天的增量是100万行,一个是50行,那统计分析如果已按照所有的表一样的方式来进行统计,这显然是有点欠妥。
所以上面的截图就是一个类似细微调整的参数
stats_persistent = 1 是要持久化性能计数器
stats_auto_recale 是控制这个表到底要不要进行自动的性能分析,例如有人ORACLE 用的顺手了,很可能会在晚上的时间来跑一边统计分析,这里 stats_auto_recalc 这里的意思是是否你要自动的进行还是手动, 最后的stats_sample_pages 是针对你索引的统计信息的精度,默认是20,增加这个数值可以提高统计信息的精度,当然你也要付出某些磁盘空间,和分析时的cpu等资源。
所以这样就对一个大表是经常被查询的HOT TABLE 还是 COLD TABLE 在这里进行分析,虽然这个表大量插入数据,但实际上查询很少,则可以降低 stats_sample_pages 的随机抽样的数字。相反,则可以适当增加。
我们来做一个测试,关于往数据库中插入数据,但之前需要注意的是python 与MYSQL 8.019相连接需要新的连接方式 mysql_connector_python
而不是之前的方式,上图的还在继续用老的方式需要将你的账户的。
CREATE USER link@% IDENTIFIED WITH mysql_native_password BY link;
否则连接中会报错
另外还有一点是,在统计分析中默认是针对 READ UNCOMMITED
的方式,其中如果有删除的记录,同时被标记的删除记录,还是要记录到统计分析中,所以大量有delete操作的情况下 RC RR 方式获得的统计分析信息就会相对准确率低。
所以就可以将 innodb_stats_include_delete 打开。但同样也会将统计分析的时间加大,并且在统计分析时会加重系统的负担。
idx_name
n_diff_pfx01 |
1743985 |
100 | name
idx_name
n_diff_pfx02 |
1761487 |
100 | name,id
idx_name
n_leaf_pages |
2722 |
NULL | Number of leaf pages
idx_name
|
size
|
3175 |
NULL | Number of pages in the index
从上面的拿出的文字来看,size 是显示整体的page
数量,n_leaf_pages 是展示当前的页节点的page的数量, n_diff_pfx01 是指单列值的不同的情况,n_diff_pfx02 是显示 两列之间不同的值。
按照我们的MYSQL 的主键设置的方式,主键和索引列的值一般是不一样的,所以这里可以认为 n_diff_pfx02 大致就是你目前的表的行数(非准确,因为出发重新统计需要数据变化10%rows)
最后需要看一下NULL 值在统计分析中的方式 innodb_stats_method
mysql 提供了3种方式
nulls_equal
所有NULL索引值都被认为是相等的
nulls_unequal
值被认为是不等的,每个NULL形成大小为1的不同的值组。
nulls_ignored
忽略空值
另外这里不便展开,null
= null
, no
, null
!= null
, no
, null 在数据库里面到底是一个什么角色,并且要不要被统计到统计信息里面来,都是应该考虑的问题,而MYSQL 将这个问题让用户来选择,实际上着也说明MYSQL 本身也对这个问题没有自己的解决方案,所以......
【MYSQL 8 统计信息持久化 与 null】大家在设计表的时候,尽量还是不要NULL 列,即使有,也不要INDEX
it.
最后留下一幅图,在正常的语句中,如果有null,都要在查询中添加一个 and
某字段 is null
or
某字段 not is null
,是有意义的,否则........
推荐阅读
- MySQL数据库(25)(外键 foreing key)
- PostgreSQL Template
- MYSQL 5.7 VS 8 用函数你三思,三思
- 如何设计出一个比较合理的数据归档系统
- PostgreSQL 如何“霸占”系统OS cache 提升查询性能
- 看电影也可以学点什么
- gitlab安装与使用
- MYSQL怎么发现处理没有commit 留下的“大”麻烦()
- PostgreSQL 一个可以调整查询代价的数据库