mysql explain預估剖析


http://www.cnblogs.com/LBSer/p/3333881.html

引子:

  使用MySQL建立了一張表country,總共有才3121行記錄。

  但是使用explain select count(*) from country;的時候,發現行數rows達到6897,讓我大吃一驚。

mysql> explain select count(*) from country;

+----+-------------+---------+------+---------------+------+---------+------+------+-------+

| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra |

+----+-------------+---------+------+---------------+------+---------+------+------+-------+

|  1 | SIMPLE      | country | ALL  | NULL          | NULL | NULL    | NULL | 6897 | NULL  |

+----+-------------+---------+------+---------------+------+---------+------+------+-------+

 

問題:為什么explain的結果和真實的結果運行不一致,並且產生這么大的誤差?

  針對這個問題,上網查了些資料,特此發博文總結下,當然自己也是剛剛使用mysql,有很多不了解的地方,希望多多指正。

一、explain是什么?

  通過explain可以查看MySQL的執行計划,從而知道MySQL是如何處理我們的SQL語句。具體來說通過explain我們能得到一系列的關鍵信息,比如哪些索引被實際使用,查詢了多少行等等。

  explain使用Rows來告知我們數據庫即將要閱讀的行數,但是實際將要閱讀的行數和explain所記載的將要閱讀的行數可能會有差異,這是因為explain並沒有真的去執行sql語句從而得出行數,而是進行了某種預估。

二、explain怎么預估行數

  找了半天得知真相的我眼淚掉下來:http://lists.mysql.com/commits/115810

1)mysql-5.5之前

  首先找到查詢第一個記錄所在的page(記為PLeft),統計PLeft里的記錄數(記為Records_PLeft),之后找到最后一個記錄所在的page(記為PRight),統計PRight的記錄數(Records_PRight),之后將Records_PLeftRecords_PRight取平均,最后乘以總共的page數目(記為Page_Num)。公式如下:

Rows = ((Records_PLeft + Records_PRight)/2)*Page_Num

  統計上講這個預估方法是很有偏的。比如總共4個page:page1(999 records), page2(1 record), page3(1 record), page4(1 record),這樣預估出來的Rows=((999+1)/2)*4 = 2000,然而實際上才總共才有1002個記錄。

2)mysql-5.5之后

  上述預估偏差大的關鍵在於有偏,而有偏的關鍵在於采樣的page數太少了,事實上只采樣了邊界2個,新算法的思路很簡單,增加采樣數目,比如采樣10個page,這樣可以在一定程度上降低偏差。

  具體來說,mysql除了邊界2個外,還沿着左側page往右連續查找8個page,如果總的page數目小於等於10個,那么預估的Rows和真實的Rows一致。

Rows = ((Records_PLeft + Records_P1 + Records_P2 + ... + Records_P8 + Records_PRight)/10)*Page_Num

   上述方法只是在一定程度上緩解了有偏的問題,但是不准確還是存在的,事實上樓主的mysql版本是5.6版本,可見還是沒有解決的很好

 三、思考

  為什么是從左往右連續選8個page,而不是在首尾之間隨機選擇8個page,既然要緩解采樣有偏的問題,那么隨機選應該更好。猜想可能有兩個原因:1)隨機選擇每次explain得到的Rows不一樣,不方便應用;2)隨機選會造成I/O開銷,尤其是數據量大的時候,畢竟explain是希望能快速得到預估結果。

  我覺得應該還有更好的算法,能實現explain效率與精度的tradeoff,希望大家能給出建議。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM