T-SQL使用經驗彙總

萬康發表於2014-06-13

表欄位

1) 欄位值在允許為空的情況下,儘量採用預設值

2) 日期型別的資料欄位,儘量採用整型型別(unix timespan),其次採用datetime型別,不要使用字串型別來存放,如:nvarchar,varchar

3) 數值型別的資料欄位,應使用sqlserver中對應的數值型別來存放,不要使用字串型別來存放,如:nvarchar,varchar

4) 欄位索引不要建太多,應根據資料表承載業務資料的實際情況進行建立索引

Select單表或多表查詢

1) 內聯表位置的擺放遵循“左大右小”原則

2) Select 後欄位名稱儘可能顯式地指定,儘可能少用*號代替

3) Select 欄位中不要使用子查詢,可尋求表關聯的方式代替

Select或Update條件

1) 儘量少用函式進行條件篩選,如:substring、charindex、isdate等

2) Where條件中的欄位儘可能是索引(但不是索引越多越好)

3) Where條件中各條件的位置優先順序排列標準: 函式表示式條件 -> 欄位比較條件 -> 字串常量條件 -> 數值常量條件

4) 少用in操作,採用exists操作代替

5) 多表關聯情況下Where中條件可放在On 關聯中

6) Where如果有多個or操作可考慮用union all 代替

7) Like條件儘量使用半模糊,如: like ‘xxx%’

8) Order by 排序欄位中少用函式表示式或欄位

9) 需要在Where 條件中進行動態判斷操作時,可以採類似如下寫法:(‘’= @id or id=@id)

複雜t-sql

1) 多個查詢結果合併union all 優於union

2) 如果有多重子查詢結果行關聯查詢,採用with 公用表示式

3) Group by 優於Distinct 關鍵字

4) 多重子查詢巢狀,儘量將篩選條件放在裡內層的子查詢中

5) Group by 分組查詢條件儘量在where中,少放在having中進行篩選,資料量超大或查詢複雜度很高的情況下少用sqlserver2005版自帶的partition by等語法

6) Group by 分組合並統計的欄位不要存在null值,對於sum求和要先isnull轉換過濾

7) 在store procedure 或function中少用字串拼裝方式生成sql指令碼,sql指令碼條件多采用引數傳入的方式,如:where id=@id ,外部應用通過資料連線請求的方式提交到sqlserver內部執行的sql指令碼也應多采用引數傳入的方式,如:where id=@id

8) 在包含有頻繁(或併發)業務邏輯的store procedure 或 function中少用cursor操作,少用#臨時表操作。對於cursor代替方案可尋求update的多表內聯更新方式,對於#臨時表代替方案可尋求檢視或with公用表示式的方式

9) 要編寫動態order by 欄位時,可採用case when進行判斷,減少拼裝字串操作

10) 表值函式內聯查詢優於表之間的關聯查詢,如 Select a.id , b.name from table1 as a OUTER APPLY fun(a.id) b Sqlserver優化與管理

執行計劃

1) 系統表sys.dm_exec_cached_plans存放sqlserver執行計劃快取

2) 系統表函式sys.dm_exec_sql_text 通過對執行計劃控制程式碼的引數可以得到具體是哪個執行計劃的名稱

通常結合的使用示例:

SELECT usecounts , p.size_in_bytes , [sql].[text] FROM sys.dm_exec_cached_plans p OUTER APPLY sys.dm_exec_sql_text (p.plan_handle) sql

各欄位意義和使用規則可參考sqlserver 自定的BookOnline幫助

DBCC命令

1) DBCC FREEPROCCACHE 清除當前執行計劃快取

2) DBCC FREESESSIONCACHE 清除當前會話狀態快取

3) DBCC FREESYSTEMCACHE('All') 清除所有快取

4) DBCC DROPCLEANBUFFERS 從緩衝池中刪除所有緩衝區

具體使用參考microsoft 官網的msdn

相關文章