SQL語句編寫與優(yōu)化規(guī)范
1 用SELECT查詢用具體字段代替“*”,且盡可能只查詢需要的字段。
2 多表查詢時,使用表的別名,就可以減少解析的時間并減少那些由列名歧義引起的語法錯誤
3 用EXISTS替代IN,用NOT EXISTS替代NOT IN
4 WHERE條件連接順序,把表關(guān)系寫在最前
例如Oracle采用自下而上的順序解析WHERE子句,表之間的條件連接必須寫在其他條件之前,把可以過濾掉大量數(shù)據(jù)的條件寫在WHERE子句的最后,按照過濾記錄數(shù)量的多少
5 刪除全表時,用TRUNCATE替代DELETE
當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放可以被恢復(fù)的信息. 如果你沒有COMMIT事務(wù),ORACLE會將數(shù)據(jù)恢復(fù)到刪除之前的狀態(tài)(準確地說是恢復(fù)到執(zhí)行刪除命令之前的狀況) 而當運用TRUNCATE時, 回滾段不再存放任何可被恢復(fù)的信息.
當命令運行后,數(shù)據(jù)不能被恢復(fù).因此很少的資源被調(diào)用,執(zhí)行時間也會很短。但只有在刪除全.表數(shù)據(jù)時才這樣使用。 ...
6 盡可能多的使用commit
對于執(zhí)行,update,語句時盡量多commit,因為系統(tǒng)性能會因commit釋放的資源而大大提高。注意事務(wù)的處理,因為commit的數(shù)據(jù)是不允許回滾的。
7 優(yōu)化GROUP BY
為提高GROUP BY的效率,可以將不需要的數(shù)據(jù)在GROUP BY之前過濾掉,減少由于數(shù)據(jù)量大而帶來的性能損耗。同時避免使用HAVING子句,HAVING只會在檢索出所有記錄之后才對結(jié)果集進行過濾,這個處理需要排序、統(tǒng)計等操作。如果能通過WHERE子句限制記
8 ORDER BY字段需建立索引
ORDER BY語句以找出非索引項或者表達式,它們會降低性能。解決這個問題的辦法就是重寫ORDER BY語句以使用索引,也可以為所使用的列建立另外一個索引,同時應(yīng)絕對避免在order by子句中使用表達式。
9 有條件的使用union-all 替代union
這樣做效率會提高3到5倍。
10 IS NULL 與 IS NOT NULL(索引失效)
不能用null作索引,任何包含null值的列都將不會被包含在索引中。即使索引有多列這樣的情況下,只要這些列中有一列含有null,該列就會從索引中排除。也就是說如果某列存在空值,即使對該列建索引也不會提高性能。
任何在where子句中使用is null或is not null的語句優(yōu)化器是不允許使用索引的。
11 對于有聯(lián)接的列,即使最后的聯(lián)接值為一個靜態(tài)值,優(yōu)化器是不會使用索引的`。(索引失效)
12 避免使用帶通配符的LIKE查詢(索引失效)
之前我認為只要含有“%”的LIKE查詢索引就會失效,經(jīng)過網(wǎng)絡(luò)資料查詢,說只有“%”13 注意or條件查詢,兩邊條件必須均建立索引才會生效(索引失效)
14 避免在索引列上使用函數(shù)或計算,如果索引是函數(shù)的一部分,則優(yōu)化器不會使用索引。(索引失效)
15 避免使用not、!=、<>(索引失效)
索引只能告訴什么存在于表中,不能告訴我們什么不存在,當數(shù)據(jù)庫遇到not、!=、<>時,索引會失效而去進行全表掃描。用“>=”代替“>”
總結(jié)
原則上,應(yīng)該盡可能的減少與數(shù)據(jù)庫的交互,但不意味著要寫一個龐大復(fù)雜的SQL來獲取所有需要的數(shù)據(jù)。對于復(fù)雜或訪問量頻繁的功能,可以考慮借助緩存來提升性能。對于表數(shù)據(jù)量過于龐大而且持續(xù)增長,考慮歸檔歷史,分開查詢;如果仍然無法提升性能,則可以從增加硬件來改善,如讀寫分離、數(shù)據(jù)庫集群等方案。
在拼寫SQL時,盡可能的將SQL拆解為簡單易讀的SQL,對于復(fù)雜邏輯可以借助程序來協(xié)同完成,一方面執(zhí)行效率不一定低,另一方面也給未來的運維、修改帶來便捷。如果設(shè)計原因?qū)е玛P(guān)聯(lián)表略多,考慮視圖、拆解、輔助表的方式來簡化查詢,降低SQL復(fù)雜度,減少表關(guān)聯(lián)查詢的數(shù)量(少于5表),且盡可能少用子查詢,視圖嵌套不要超過2層。
【SQL語句編寫與優(yōu)化規(guī)范】相關(guān)文章: