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的資料分佈
- 實驗-資料分佈對執行計劃的影響.txt
- hive1.2偽分佈mysql資料庫配置詳解HiveMySql資料庫
- 地圖網點分佈圖怎麼做,如何製作地圖資料分佈圖地圖
- 如何根據資料的分佈來選擇ML演算法? - Reddit演算法
- Laravel的mysql資料分離想法LaravelMySql
- 核對主備庫表的資料sql語句(待完善)SQL
- MySQL 資料對比MySql
- MySQL偏移量的一點分析MySql
- 德勤:是時候認真對待資料了
- 分散式儲存中的資料分佈策略分散式
- 容器如何對待沒有部署為Web應用的一部分的servlet?WebServlet
- 資料統計分析 — 泊松分佈
- 資料分佈決定SQL寫法SQL
- Hash分割槽表及資料分佈
- mongodb資料庫範圍分片資料分佈不均勻MongoDB資料庫
- 如何檢視某一表空間的資料檔案都分佈了哪些資料物件薦物件
- 資料並非都是正態分佈:三種常見的統計分佈及其應用
- GBase8a資料分佈規劃
- oracle Mysql PostgreSQL 資料庫的對比OracleMySql資料庫
- 「分散式技術專題」資料分佈(原理、資料分片)分散式
- 如何正確的對待設計模式——我的觀點設計模式
- ICLR 2024 Oral | 應對隨時間變化的分佈偏移,西安大略大學等提出學習時序軌跡方法ICLR
- 在Java中地域分佈資料庫是如何連線和進行CRUD 操作的?Java資料庫
- 商場分佈圖是怎麼做,地圖資料分佈圖怎麼做地圖
- 多工學習中的資料分佈問題(一)
- 多工學習中的資料分佈問題(二)
- ceph解讀:crush分散式資料分佈的問題分散式
- 我們應該如何對待技術信仰?
- MYSQL 5.6 5.7處理資料分佈不均的問題(eq_range_index_dive_limit引數)MySqlIndexMIT
- margin系列之與相對偏移的異同
- 如何快速找到MYSQL binlog中的大事物以及生成量分佈(infobin工具)MySql
- 關於共軛分佈,beta分佈,二項分佈和Dirichlet分佈、多項式分佈的關係
- 如何生成指定分佈的隨機數隨機