天天看點

為什麼會存在using filesort

當使用explain分析SQL時常常會遇到extra的其中一值為using

filesort,如:

PRIMARY KEY (`id`),

  KEY `uid` (`uid`)

explain select * from t_talbe where uid=1order by id;

extra結果為:Using

where; Using filesort

手冊中對Using filesort解釋是“MySQLmust

do an extra pass to find out how to retrieve the rows in sorted order. Thesort is done by going through all rows according to the join type and storingthe sort key and pointer to the row for all rows that match the WHERE clause.”。

假設根據條件會得到兩條記錄A(id1,uid1,*)和B(id2,uid2,*);根據KEY

`uid` (`uid`)排序規則,很容易得到這兩條結果,找到的兩個uid,即uid1和uid2,它們被檢索出來的先(假如uid1)後(假如uid2)順序已經知道了它們之間的大小關系,然而,id1和id2,誰大誰小呢?不知道。必須在它們之間進行比較,如果有n條結果集,必須對它們全部取出來比較,才能知道第一個記錄是哪一個。第二個,……第n個呢?

現在先來了解一下index的一個思想,假設有“KEY

key_name(`k1`,`k2`,……,`kn`)”,我們知道記錄集會:

 1。先按照字段k1排序,

 2。在k1相同的情況下,按k2排序,

 3。在k2也相同的情況下,再按k3排序,依此類推,

 4。最後是kn。

由此規則下可知,在一個隊列Lx中,存在兩個鄰近的點Li(ki,1,ki,2,……,ki,n)和Li+1(ki+1,1,ki+1,2,……,ki+1,n),如果ki,1=ki+1,1,那麼知道ki,2和ki+1,2在不需要比較的情況下就可以知道它們之間的關系。

所有針對以上的例子,把KEY `uid` (`uid`)修改成KEY

`u_id` (`uid`,`id`)可得以解決。

但,

例2。select

* from t_talbe where uid=1 order by id,uid;還是沒辦法,因為不可能建立INDEX

`u_id_u` (`uid`,`id`,`uid`);

例3。select

* from t_talbe where uid!=1 order by id;(possible_keys:u_f,uid;key:null;extra:Using

where; Using filesort。)

 其中:uid=2(id|1,2,3,4),和uid=3(id|1,2,3,4),為了得到id的排序,對于`u_id`(`uid`,`id`)還得把所有記錄取出來比較。

順便說一下,有時候存在Using filesort,也未必是什麼大不了的:如

例4。

select * from t_talbe order by id;隻是告訴你它使用了“all

rows”。