SQL編碼中注意的性能問題
1、選擇合適的數據類型為列選擇最小化的數據類型
如果一列中的文本長度不一,使用VARCHAR而不是CHAR
不存儲Unicode不要使用NVARCHAR或者NCHAR
如果一行的長度不超過8000,使用VARCHAR而不是TEXT
對於僅存數字的列要使用數字類型而不要用字符類型
不要使用字符串類型存儲日期數據。
2、謹慎使用觸發器
保持觸發器內的代碼最小化
可能的情況下盡量用其他更高效的技術替代觸發器
盡量避免回滾觸發器
3、隻返回需要的數據
橫向來看,不要返回自己不需要的列,盡量不要使用select *
縱向來看,不要返回自己不需要的行,盡量使用where條件來過濾自己需要的內容
考慮使用TOP
考慮分頁
對於聚合查詢,可以用HAVING子句進一步限定返回的行。
4、盡量少做重複的工作
控製同一語句的多次執行,特別是一些基礎數據的多次執行。
減少多次的數據轉換,也許需要數據轉換是設計的問題,但是減少次數是可以做到的。
合並對同一表同一條件的多次UPDATE,
UPDATE操作不要拆成DELETE操作+INSERT操作的形式,雖然功能相同,但是性能差別是很大的。
不要寫一些沒有意義的查詢。
插入大量數據時,盡量不要使用循環,可以使用CTE,如果要使用循環,也放到一個事務中;
5、注意臨時表用法
在複雜係統中,臨時表很難避免,關於臨時表需要注意:
語句很複雜,連接太多,可以考慮用臨時表分步完成。
多次用到一個大表的同一部分數據,考慮用臨時表暫存數據。
需要綜合多個表的數據,形成一個結果,可以考慮用臨時表分步匯總這多個表的數據。
其他情況下,應該控製臨時表和表變量的使用。
注意排序規則。
關於臨時表產生使用SELECT INTO和CREATE TABLE + INSERT INTO的選擇.
6、避免使用遊標
對於某些逐行的處理考慮放在客戶端
考慮使用關聯的子查詢代替遊標
必須使用遊標時注意以下問題:
使用高效的遊標類型(例如 forward-only)
使用服務器端遊標時保持結果集盡量小。
遊標使用結束時不能僅僅CLOSE,還要DEALLOCATE。
7、 恰當使用連接
對於頻繁連接的表用於連接的列需要有合適的索引
用於連接的列盡量使用相同的數據類型
避免將唯一值很少的列用過連接列,否則會導致scan
如果有些查詢需要對4個或更多的表進行連接,可以考慮低範化一些表
8、 其他需要注意的地方
問題發現的越早解決的成本越低,很多性能問題可以在編碼階段就發現,為了提早發現性能問題,需要注意:
程序員注意、關心各表的數據量。
編碼過程和單元測試過程盡量用數據量較大的數據庫測試,最好能用實際數據測試。
每個SQL語句盡量簡單
不要頻繁更新有觸發器的表的數據
注意數據庫函數的限製以及其性能
最後更新:2017-04-03 12:56:29