https://juejin.im/book/5bffcbc9f265da614b11b731/section/5c061b43f265da612859e3fd
目前統(tǒng)計數(shù)據(jù)默認存儲在磁盤上(就是重啟后還在), 是以表為單位來收集和存儲 的 (可以設置為一些表的統(tǒng)計數(shù)據(jù)在內(nèi)存里面一些在磁盤)
存儲在磁盤的統(tǒng)計數(shù)據(jù), 實際在mysql
庫的 2個表里面
- innodb_
index
_stats - innodb_
table
_stats
innodb_index
_stats
比如這么一行數(shù)據(jù)
意思是 clouddb01庫的 project_company表 大概有95行數(shù)據(jù),大概聚簇索引有3頁, 其他索引有0頁, 就是還沒索引
行數(shù)的估計
有個雙方選幾個(默認20個可以按表調(diào))葉子節(jié)點頁面,得到每頁平均記錄條數(shù), 再乘以 葉節(jié)點數(shù)
索引有幾頁的估計
從數(shù)據(jù)字典 (也叫系統(tǒng)內(nèi)部表,用戶只能從information_schama庫看到其中一些數(shù)據(jù),information_schama就是這個作用,啟動的時候吧數(shù)據(jù)字典的一些數(shù)據(jù)拿過來)的SYS_INDEXES可以拿到各個索引的 根頁面
根頁面的Page Header
(數(shù)據(jù)頁獨有的結果) 里面有2個Segment Header
(2個剛好一個給葉子段,一個給非葉子段), Segment Header
的作用就是找到INODE Entry
,INODE Entry
是對段的描述(可以找到3條鏈的基節(jié)點和幾個零散頁的頁號),基節(jié)點記載鏈的長度
雖然鏈里面只是申請到的空間, 肯定還有空著的, 但是估算的時候都算進去
innodb_table
_stats
以索引為單位, 記載統(tǒng)計 key-value
- n_leaf_pages:葉子節(jié)點 多少頁面。
- size:共占用多少頁面年堆。
- n_diff_pfxNN:列不重復的值有多少,NN是給聯(lián)合索引的列編號
統(tǒng)計數(shù)據(jù)的更新
默認是自動更新的, 變更記錄超過10% 就重新異步(就是一般會慢幾秒)計算
我也可以手動調(diào)用,指定表讓其馬上更新其統(tǒng)計
因為統(tǒng)計值就是普通的在表里面的數(shù)據(jù), 我也可以手動去改它
索引上不重復值 : Cardinality 基數(shù)
這個值很有用
比如:
-
key IN ('xx1', 'xx2', ..., 'xxn');
要估算滿足條件的條數(shù)
in(里面有超過200的參數(shù)) 用index dive
不劃算
Rows/Cardinality來估算條數(shù) -
t1 JOIN t2 ON t1.column = t2.key WHERE ...
t1.column
有幾條的估算
對null的處理
比如索引上有 1,2,null,null 算有4種值,還是2種值,還是3種值 用戶可以自己設定 (用innodb_stats_method