https://juejin.im/book/5bffcbc9f265da614b11b731/section/5c061b43f265da612859e3fd
目前统计数据默认存储在磁盘上(就是重启后还在), 是以表为单位来收集和存储 的 (可以设置为一些表的统计数据在内存里面一些在磁盘)
存储在磁盘的统计数据, 实际在mysql
库的 2个表里面
- innodb_
index
_stats - innodb_
table
_stats
innodb_index
_stats
比如这么一行数据
意思是 clouddb01库的 project_company表 大概有95行数据,大概聚簇索引有3页, 其他索引有0页, 就是还没索引
行数的估计
有个双方选几个(默认20个可以按表调)叶子节点页面,得到每页平均记录条数, 再乘以 叶节点数
索引有几页的估计
从数据字典 (也叫系统内部表,用户只能从information_schama库看到其中一些数据,information_schama就是这个作用,启动的时候吧数据字典的一些数据拿过来)的SYS_INDEXES可以拿到各个索引的 根页面
根页面的Page Header
(数据页独有的结果) 里面有2个Segment Header
(2个刚好一个给叶子段,一个给非叶子段), Segment Header
的作用就是找到INODE Entry
,INODE Entry
是对段的描述(可以找到3条链的基节点和几个零散页的页号),基节点记载链的长度
虽然链里面只是申请到的空间, 肯定还有空着的, 但是估算的时候都算进去
innodb_table
_stats
以索引为单位, 记载统计 key-value
- n_leaf_pages:叶子节点 多少页面。
- size:共占用多少页面。
- n_diff_pfxNN:列不重复的值有多少,NN是给联合索引的列编号
统计数据的更新
默认是自动更新的, 变更记录超过10% 就重新异步(就是一般会慢几秒)计算
我也可以手动调用,指定表让其马上更新其统计
因为统计值就是普通的在表里面的数据, 我也可以手动去改它
索引上不重复值 : Cardinality 基数
这个值很有用
比如:
-
key IN ('xx1', 'xx2', ..., 'xxn');
要估算满足条件的条数
in(里面有超过200的参数) 用index dive
不划算
Rows/Cardinality来估算条数 -
t1 JOIN t2 ON t1.column = t2.key WHERE ...
t1.column
有几条的估算
对null的处理
比如索引上有 1,2,null,null 算有4种值,还是2种值,还是3种值 用户可以自己设定 (用innodb_stats_method
网友评论