上接SQL Server 查詢性能優化——索引與SARG(二)
2 請不要進行負向查詢
除了不應該對字段數據進行計算外,非SARG 語句的格式語句還包含在WHERE條件子句中,使用負向查詢操作符。
如NOT 、!=、<> 、!>、!<、NOT EXISTS 、NOT IN及NOT LIKE 等,因為通過有順序的索引結構,SQL SERVER 可以有效地利用二分法進行查找,快速找到相應的數據,但是如果查詢條件是不要什么數據,其余的都要(就是負向查詢), 則 無法利用索引進行二分查找,只能進行全表掃描或聚集索引掃描。
以下同樣是負向操作健立的SARG 條件查詢與非SARG 條件查詢范例。從中可以看出兩者的執行成本是不一樣的,相差十倍左右,但是其數據查詢的記錄數量也不一樣。個人理解查詢優化程序是根據數據查詢的記錄數量,來決定使用哪種執行計划。
邏輯讀 |
執行成本 | ||||
SELECT * FROM [WBK_PDE_ LIST_ORG_ HISTROY] where QTY_1=312
|
有主鍵(索引1,索引2) |
1 |
表'WBK_PDE_LIST_ORG_HISTROY'。掃描計數1,邏輯讀取137 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。 |
137 |
|
|
0.121935 |
||||
無主鍵(索引2) |
2 |
表'WBK_PDE_LIST_ORG_HISTROY'。掃描計數1,邏輯讀取43 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
|
43 |
||
|
0.121935 |
||||
SELECT * FROM [WBK_PDE_ LIST_ORG_ HISTROY] where QTY_1<>312
|
有主鍵(索引1,索引2) |
3 |
表'WBK_PDE_LIST_ORG_HISTROY'。掃描計數1,邏輯讀取1314 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
|
1314 |
|
|
1.03687 |
||||
無主鍵(索引2) |
4 |
表'WBK_PDE_LIST_ORG_HISTROY'。掃描計數1,邏輯讀取1306 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
|
1306 |
||
|
1.03687 |
||||
小結:
查詢語句 |
邏輯讀 |
查詢記錄數量 |
執行成本 |
1 |
137 |
37 |
0.121935 |
2 |
43 |
37 |
0.121935 |
3 |
1314 |
60796 |
1.03687 |
4 | 1306 | 60796 | 1.03687 |
3 不要在WHERE子句中對字段使用函數
在查詢語句中對字段使用函數,就是對字段數據進行計算,所以這些都不算是SARG。使用函數之后 ,SQL SERVER 需要將數據表內所有記錄的相關字段輸入到函數中,如果有100萬條記錄,就需要調用函數100萬次,這將是性能殺手。
下面列出兩個非SARG與SARG的查詢成本區別的示例。
邏輯讀 |
||||
SELECT * FROM [WBK_PDE_LIST_ORG_HISTROY] where dbo.f_qty(QTY_1,G_QTY)=400 |
||||
數值函數計算 |
1 |
表'WBK_PDE_LIST_ORG_HISTROY'。掃描計數1,邏輯讀取1428 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
|
1428 |
|
|
1.03687 |
|||
SELECT * FROM [WBK_PDE_LIST_ORG_HISTROY] where QTY_1=200 and G_QTY=200 |
||||
2 |
表'WBK_PDE_LIST_ORG_HISTROY'。掃描計數1,邏輯讀取428 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
|
428 |
||
|
0.42645 |
|||
SELECT * FROM [WBK_PDE_LIST_ORG_HISTROY] where dbo.[f_ByteLeft](wbook_no,14)='BE404942450013' |
||||
字符函數計算 |
3 |
表'Worktable'。掃描計數0,邏輯讀取0 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。 表'WBK_PDE_LIST_ORG_HISTROY'。掃描計數2,邏輯讀取850 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。 |
850 |
|
|
1.03904 |
|||
SELECT * FROM [WBK_PDE_LIST_ORG_HISTROY] where wbook_no='BE404942450013' |
||||
4 |
表'WBK_PDE_LIST_ORG_HISTROY'。掃描計數1,邏輯讀取3 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
|
3 |
||
|
0.0033071 |
|||
小結:
查詢語句 |
邏輯讀 |
查詢記錄數量 |
執行成本 |
1 |
1428 |
3873 |
1.03687 |
2 |
136 |
37 |
0.42645 |
3 |
850 |
3873 |
1.03904 |
4 | 3 | 22 | 0.0033071 |