order by與索引
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
等。
相關文章
- MYSQL order by排序與索引關係總結MySql排序索引
- MySql ORDER BY索引是否失效MySql索引
- oracle order by索引是否使用的情況Oracle索引
- SQLServer索引優化(1):對於有order by欄位的建索引策略SQLServer索引優化
- 【開發總結】order by 為什麼沒有走索引?索引
- 如何使用使用 HAVING 與 ORDER BY?
- 索引與null(二):組合索引索引Null
- 索引與null(一):單列索引索引Null
- in、exists與索引索引
- CSS orderCSS
- 淺談聚簇索引與非聚簇索引索引
- MySQL中ORDER BY與LIMIT一起使用(有坑)MySqlMIT
- MySQL Order by 語句用法與最佳化詳解MySql
- 匿名類 與 索引重建索引
- Order by 優化優化
- 淺談MySQL的B樹索引與索引優化MySql索引優化
- InnoDB索引與底層原理索引
- 《PostgreSQL》 索引與最佳化SQL索引
- MongoDB慢查詢與索引MongoDB索引
- ES 文件與索引介紹索引
- sql server 索引闡述系列七 索引填充因子與碎片SQLServer索引
- Elasticsearch之索引模板index template與索引別名index aliasElasticsearch索引Index
- [Javascript] Object property orderJavaScriptObject
- MySQL 之 ORDER BY FIELDMySql
- mysql order by 優化MySql優化
- CSS3 orderCSSS3
- PostgreSQL中索引與CTE簡介SQL索引
- elasticsearch(三)----索引建立與刪除Elasticsearch索引
- MongoDB索引與優化詳解MongoDB索引優化
- Mysql索引的建立與刪除MySql索引
- MySQL索引與查詢優化MySql索引優化
- MySQL 表與索引設計攻略MySql索引
- MySQL, Incorrect usage of UNION and ORDER BYMySql
- [LintCode] Binary Tree Level Order
- MyBatis order by失效問題MyBatis
- order by改分組排序排序
- MySQL Order BY 排序過程MySql排序
- 跳槽必看MySQL索引:B+樹原理揭秘與索引優缺點分析MySql索引