order by的兩種實現方法以及與索引的介紹

2021-12-30 06:14:42 字數 1967 閱讀 9662

order by 通常會有兩種實現方法,乙個是利用有序索引自動實現,也就是說利用有序索引的有序性就不再另做排序操作了。另乙個是把結果選好之後再排序。

用有序索引這種,當然是最快的,不過有一些限制條件,來看下面的測試。

測試資料:student表有兩個欄位id ,sid ,id是主鍵。一共有20w條記錄,id從1到200000,sid也是從1到200000的資料。

第一種情況 :

order by的字段不在where條件也不在select中

select sid from zhuyuehua.student where sid < 50000 order by id;第二種情況 :

order by的字段不在where條件但在select中。

select id,sid from zhuyuehua.student where sid < 50000 order by id;第三種情況 :

order by的字段在where條件但不在select中。

select sid from zhuyuehua.student where sid < 50000 and id < 50000 order by id;第四種情況 :

order by的字段在where條件但不在select中。倒序排列

select sid from zhuyuehua.student where sid < 50000 and id < 50000 order by id desc;測試結果:

order by的字段不在where條件不在select中 有排序操作

order by的字段不在where條件但在select中 有排序操作

order by的字段在where條件但不在select中 無排序操作

order by的字段在where條件但不在select中(倒序) 無排序操作

結論:當order by 字段出現在where條件中時,才會利用索引而無需排序操作。其他情況,order by不會出現排序操作。

分析:為什麼只有order by 字段出現在where條件中時,才會利用該字段的索引而避免排序。這要說到資料庫如何取到我們需要的資料了。

一條sql實際上可以分為三步。

1.得到資料

2.處理資料

3.返回處理後的資料

比如上面的這條語句select sid from zhuyuehua.student where sid < 50000 and id < 50000 order by id desc

第一步:根據where條件和統計資訊生成執行計畫,得到資料。

第二步:將得到的資料排序。

當執行處理資料(order by)時,資料庫會先檢視第一步的執行計畫,看order by 的字段是否在執行計畫中利用了索引。如果是,則可以利用索引順序而直接取得已經排好序的資料。如果不是,則排序操作。

第三步:返回排序後的資料。

另外:上面的5萬的資料sort只用了25ms,也許大家覺得sort不怎麼占用資源。可是,由於上面的表的資料是有序的,所以排序花費的時間較少。如果 是個比較無序的表,sort時間就會增加很多了。另外排序操作一般都是在記憶體裡進行的,對於資料庫來說是一種cpu的消耗,由於現在cpu的效能增強,對 於普通的幾十條或上百條記錄排序對系統的影響也不會很大。但是當你的記錄集增加到上百萬條以上時,你需要注意是否一定要這麼做了,大記錄集排序不僅增加了 cpu開銷,而且可能會由於記憶體不足發生硬碟排序的現象,當發生硬碟排序時效能會急劇下降。

注:oracle或者db2都有乙個空間來供sort操作使用(上面所說的記憶體排序),如oracle中是使用者全域性區(uga),裡面有sort_area_size等引數的設定。如果當排序的資料量大時,就會出現排序溢位(硬碟排序),這時的效能就會降低很多了。

總結:當order by 中的字段出現在where條件中時,才會利用索引而不排序,更準確的說,order by 中的字段在執行計畫中利用了索引時,不用排序操作。

這個結論不僅對order by有效,對其他需要排序的操作也有效。比如group by 、union 、distinct等。

RMQ的兩種實現方法

st表實現rmq rmq演算法 range minimum maximum query 是求區間極值的高效演算法,依據所需實現的不同效能可以有多種寫法,這裡主要講基於線段樹和稀疏表 sparse table 的兩種方法 線段樹是維護區間的一類高效資料結構,依據這個特性,我們可以用線段樹實現rmq演算...

List排序的兩種實現方法

利用collections.sort方法可以對列表進行排序collections有兩個sort方法 1.sort listlist 2.sort listlist comparator c 方法一 只需要傳入乙個list即可,但是該list中的元素需要實現comparable介面,覆蓋compare...

屬性動畫的兩種實現方法

方法一 根據資料processlist解析出 totaltime,使用 animatorset 來組合動畫,並把每一組動畫加入animations 進行管理。private float totaltime 0 private listanimations new arraylist private ...