MySQL:如何對待分佈偏移的資料
btr_estimate_n_rows_in_range_low 函式用於非唯一訪問的行數評估也就是在執行計劃生成階段會去訪問實際的資料,儘可能的得到正確的執行計劃,這個過程叫做dive。其和引數eq_range_index_dive_limit有關,如果引數設定1那麼將禁用dive功能,使用統計資料進行執行計劃的生成。但某些時候MySQL 5.7根據統計資料並不能得到正確的執行計劃,因此才有了dive,但是dive會產生額外的代價,這個過程是需要實際訪問資料塊的。
常用的比如非唯一索引的資料訪問,還有> <等這些範圍掃描都是需要用到這個函式。下面來簡單的看一下。其輸入的引數包含了index 索引的相關的資訊,範圍的起始tuple和結束tuple首先透過btr_cur_search_to_nth_level函式進行定位獲取起點記錄
然後透過btr_cur_search_to_nth_level函式定位到終點記錄透過cursor獲取到path,假設起點的path為path1 終點的path為path2path為一個陣列,其中儲存了查詢的路徑,然後會迴圈的從頂層節點到葉子節點進行判斷,其中包含了
/** A slot in the path array. We store here info on a search path down thetree. Each slot contains data on a single level of the tree. */struct btr_path_t { /* Assume a page like: records: (inf, a, b, c, d, sup) index of the record: 0, 1, 2, 3, 4, 5 */ /** Index of the record where the page cursor stopped on this level (index in alphabetical order). Value ULINT_UNDEFINED denotes array end. In the above example, if the search stopped on record 'c', then nth_rec will be 3. */ ulint nth_rec; /** Number of the records on the page, not counting inf and sup. In the above example n_recs will be 4. */ ulint n_recs; /** Number of the page containing the record. */ ulint page_no; /** Level of the page. If later we fetch the page under page_no and it is no different level then we know that the tree has been reorganized. */ ulint page_level;};
最終獲取最後的估計得行數,如果它們起點和終點的行數過多,那麼只會精確統計10個塊的資料(N_PAGES_READ_LIMIT),這個在btr_estimate_n_rows_in_range_low呼叫的btr_estimate_n_rows_in_range_on_level函式中,剩下就是取得平均值了大概為:
n_rows = n_rows_on_prev_level * n_rows / n_pages_read;
n_rows_on_prev_level就是實際的指向的塊數,因為每一個上層節點記錄指向葉子節點的一個block,n_pages_read就是大概10個塊,n_rows就是10個塊包含的行數。最終得到的n_rows就是一個大概的統計值了。這還是很有代表性的。
最終我們看到對於2層結構的索引,可能需要訪問10(取樣塊)+2(leaf)+1(root)個塊,這是有一定代價的。預設MySQL是開啟了這個功能的,因此我們會發現如下的表可以得到正確的執行計劃,比如性別列索引,其中30行,29行為男性,1行為女性,下面是執行計劃示例,可以看到禁用dive後不能得到正確的執行計劃:
mysql> set eq_range_index_dive_limit=100;Query OK, 0 rows affected (0.00 sec)mysql> desc select * from testdvi3 where sex='M';+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------------+| 1 | SIMPLE | testdvi3 | NULL | ALL | sex | NULL | NULL | NULL | 30 | 96.67 | Using where |+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------------+1 row in set, 1 warning (2.74 sec)mysql> desc select * from testdvi3 where sex='W';+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+| 1 | SIMPLE | testdvi3 | NULL | ref | sex | sex | 9 | const | 1 | 100.00 | NULL |+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+1 row in set, 1 warning (2.00 sec)mysql> set eq_range_index_dive_limit=1;Query OK, 0 rows affected (0.00 sec)mysql> desc select * from testdvi3 where sex='W';+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+| 1 | SIMPLE | testdvi3 | NULL | ref | sex | sex | 9 | const | 15 | 100.00 | NULL |+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+1 row in set, 1 warning (0.00 sec)mysql> desc select * from testdvi3 where sex='M';+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+| 1 | SIMPLE | testdvi3 | NULL | ref | sex | sex | 9 | const | 15 | 100.00 | NULL |+----+-------------+----------+------------+------+---------------+------+---------+-------+------+----------+-------+
原文連結:http://blog.itpub.net/7728585/viewspace-2707569/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978212/viewspace-2708260/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 談談如何像對待產品一樣對待資料
- 像物件一樣對待資料物件
- 對待資料質量的28個原則
- 全自動化資料洞察!資料分佈對比視覺化!⛵視覺化
- 淺談HBase的資料分佈
- 地圖網點分佈圖怎麼做,如何製作地圖資料分佈圖地圖
- MySQL 資料對比MySql
- Laravel的mysql資料分離想法LaravelMySql
- 如何根據資料的分佈來選擇ML演算法? - Reddit演算法
- 德勤:是時候認真對待資料了
- 分散式儲存中的資料分佈策略分散式
- 資料統計分析 — 泊松分佈
- GBase8a資料分佈規劃
- oracle Mysql PostgreSQL 資料庫的對比OracleMySql資料庫
- mongodb資料庫範圍分片資料分佈不均勻MongoDB資料庫
- ICLR 2024 Oral | 應對隨時間變化的分佈偏移,西安大略大學等提出學習時序軌跡方法ICLR
- 資料並非都是正態分佈:三種常見的統計分佈及其應用
- CAD如何批次偏移物件?物件
- 「分散式技術專題」資料分佈(原理、資料分片)分散式
- 多工學習中的資料分佈問題(一)
- 多工學習中的資料分佈問題(二)
- 在Java中地域分佈資料庫是如何連線和進行CRUD 操作的?Java資料庫
- 商場分佈圖是怎麼做,地圖資料分佈圖怎麼做地圖
- MySQL資料庫中的分組函式ROLLUPMySql資料庫函式
- 直播賣貨系統,如何實現mysql資料庫的讀寫分離MySql資料庫
- MySQL 資料庫的對庫的操作及其資料型別悔鋒MySql資料庫資料型別
- 如何生成指定分佈的隨機數隨機
- 【趙強老師】利用Python完成資料分佈特徵的分析Python特徵
- 如何區分大資料的屬性大資料
- MySQL資料庫之分庫分表方案MySql資料庫
- PHP 原生操作 Mysql 分頁資料案例PHPMySql
- MySQL 是如何實現資料的排序的?MySql排序
- 當面試官問到:《MySQL資料庫的鎖機制》該如何拿分?面試MySql資料庫
- Java 支援的資料型別與 MySQL 支援的資料型別對比Java資料型別MySql
- 如何通俗理解泊松分佈?
- 詳解Ceph系統資料是如何佈局的?
- 2021年Gamestop商店全球分佈(附原資料表) GAM
- MySQL資料庫資料一致性比對的方案的探討MySql資料庫