當數據量小的時候,SQL優化或許可有可無,可是當數據量達到必定量級以後,性能優化將變得相當重要,甚至決定系統成敗。數據庫
臨時表性能優化
在臨時表指定字段建立索引。函數
刪除重複記錄性能
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHEREX.EMP_NO = E.EMP_NO);
用Where子句替換HAVING 子句優化
避免使用 HAVING 子句, HAVING 只會在檢索出全部記錄以後纔對結果集進行過濾.spa
用UNION替換OR或者INcode
(適用於索引列)一般狀況下,用UNION 替換WHERE 子句中的OR將會起到較好的效果. 對索引列使用OR 將形成全表掃描.blog
區分in和exist索引
select * from 表A where id in (select id from 表B)
這句至關於進程
select * from 表A where exists(select * from 表B where 表B.id=表A.id)
若是是exists,那麼之外層表爲驅動表,先被訪問,若是是IN,那麼先執行子查詢。
因此IN適合於外表大而內表小的狀況;EXISTS適合於外表小而內表大的狀況
緣由:結果不許確,查詢性能低下
建議:在寫查詢時,儘可能避免使用Not In,而轉換爲本文提供的Not Exists等價形式,將會減小不少麻煩。
SQL with(unlock)與with(readpast)
全部Select加With(NoLock)解決阻塞死鎖,在查詢語句中使用NOLOCK和READPAST,處理一個數據庫死鎖的異常時候,其中一個建議就是使用 NOLOCK 或者 READPAST 。
對於非銀行等嚴格要求事務的行業,搜索記錄中出現或者不出現某條記錄,都是在可容忍範圍內,因此碰到死鎖,應該首先考慮,咱們業務邏輯是否能容忍出現或者不出現某些記錄,而不是尋求對雙方都加鎖條件下如何解鎖的問題。 NOLOCK 和 READPAST 都是處理查詢、插入、刪除等操做時候,如何應對鎖住的數據記錄。可是這時候必定要注意NOLOCK 和 READPAST的侷限性,確認你的業務邏輯能夠容忍這些記錄的出現或者不出現, 簡單來講:
NOLOCK 可能把沒有提交事務的數據也顯示出來。
READPAST 會把被鎖住的行不顯示出來。
不使用NOLOCK和READPAST,在Select操做時候則有可能報錯誤:事務(進程 ID **)與另外一個進程被死鎖在鎖資源上,而且已被選做死鎖犧牲品。
建立索引的的字段儘可能小,最好是數值,好比整形int等;
對於頻繁修改的字段,儘可能不要建立索引,維護索引的成本很高,並且更容易產生索引碎片;
按期的索引維護,如索引碎片的修復等;
不要創建或維護沒必要要的重複索引,會增長修改數據(新增、修改、刪除數據)的成本;
使用惟一性高的字段建立索引,切不可在性別這樣的低惟一性的字段上建立索引;
在SQL語句中,儘可能不要在Where條件中使用函數、運算符或表達式計算,會形成索引沒法正常使用;
應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描;
應儘可能避免在 where 子句中使用!=或<>操做符,不然將致使引擎放棄使用索引而進行全表掃描;