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 本身也對這個問題沒有自己的解決方案,所以...... 

大家在設計表的時候,儘量還是不要NULL 列,即使有,也不要INDEX it.

最後留下一幅圖,在正常的語句中,如果有null,都要在查詢中添加一個 and  某字段 is null  or  某字段 not is null  ,是有意義的,否則........

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章