使用高效的查詢
- 參數(shù)是子查詢時(shí),使用EXISTS代替IN
如果連接列上建立了索引,只需查詢索引即可;
如果使用exists,那么只查到一行數(shù)據(jù)滿足條件就會終止查詢,不像IN會掃描全表。 - 參數(shù)是子查詢時(shí),使用連接代替IN
避免排序
-
會進(jìn)行排序的代表性的運(yùn)算:
- group by 子句
- order by 子句
- 聚合函數(shù)(SUM、COUNT、AVG、MAX、MIN)
- DISTINCT
- 集合運(yùn)算符(UNION、INTERSECT、EXCEPT)
- 窗口函數(shù)(RANK、ROW_NUMBER)
- 盡量避免無謂的排序。
使用ALL可選項(xiàng)不會進(jìn)行排序。
使用EXISTS代替DISTINCT。
極值函數(shù)中使用索引(MAX、MIN)
能寫在WHERE子句里的條件不要寫在HAVING子句里。HAVING子句是針對聚合后生成的視圖進(jìn)行篩選的,但是很多時(shí)候聚合后的視圖都沒有繼承原表的索引結(jié)構(gòu)。
在GROUP BY子句和ORDER BY子句中使用索引
利用索引
- 使用索引時(shí),條件表達(dá)式的左側(cè)應(yīng)該是原始字段。
- 指定IS NULL和IS NOT NULL會使得索引無法使用。
-
<>、!=、NOT IN等否定形式不能用到索引。 - 使用
OR索引無法使用,除非是位圖索引,但這會增大性能的開銷。 - 使用聯(lián)合索引時(shí),列的順序錯(cuò)誤,會導(dǎo)致索引無法使用。如果無法保證查詢條件里列的順序與索引一致,可以將聯(lián)合索引拆分為多個(gè)索引。
- 使用
LIKE時(shí),只有前方一致的匹配才能用到索引。如:
select * from sometable where col_1 like '%a'; -- 不會使用索引
select * from sometable where col_1 like '%a%'; -- 不會使用索引
select * from sometable where col_1 like 'a%'; -- 會使用索引
- 默認(rèn)的類型轉(zhuǎn)換不僅會增加額外的性能開銷,還會導(dǎo)致索引不可用,在需要類型轉(zhuǎn)換的時(shí)候顯示地進(jìn)行類型轉(zhuǎn)換(轉(zhuǎn)換要寫在條件表達(dá)式的右邊)。
減少中間表
- 頻繁使用中間表會帶來兩個(gè)問題:1.展開數(shù)據(jù)需要耗費(fèi)內(nèi)存資源,2.原始表中的索引不容易使用到。盡量減少中間表的使用也是提升性能的一個(gè)方法。
- 先進(jìn)行連接再進(jìn)行聚合。
- 合理使用視圖。
個(gè)人博客:https://jenkinwang.github.io/
參考書籍:《SQL進(jìn)階教程》[日]MICK/著 吳巖昌/譯