翻譯自:
當設定表的索引時,在效能上有乙個微妙的平衡:太多的索引將影響你的insert/update/delete操作。但是索引不足又將影響你的select操作。本文將著眼於索引的列順序和如何影響查詢計畫及效能。
示例sqlserver表和資料集:
-- tablecreation logic
create
table
[dbo]
.[table1] (
[col1]
[int]
notnull,
[col2]
[int]
null,
[col3]
[int]
null,
[col4]
[varchar]
(50)
null) go
create
table
[dbo]
.[table2] (
[col1]
[int]
notnull,
[col2]
[int]
null,
[col3]
[int]
null,
[col4]
[varchar]
(50)
null) go
alter
table
dbo.
table1
addconstraint
pk_table1
primary
keyclustered
(col1)
go alter
table
dbo.
table2
addconstraint
pk_table2
primary
keyclustered
(col1)
go --populate tables
declare
@val
int
select
@val
=1while
@val
< 1000
begin
insert
into
dbo.
table1
(col1
,col2
,col3
,col4
)values
(@val
,@val
,@val
,'test')
insert
into
dbo.
table2
(col1
,col2
,col3
,col4
)values
(@val
,@val
,@val
,'test')
select
@val
=@val
+1end go
--create multi-column index on table1
create
nonclustered
index
ix_table1_col2col3
ondbo
.table1
(col2
,col3)
with
(statistics_norecompute
=off
,ignore_dup_key
=off,
allow_row_locks=on
,allow_page_locks=on
) on[primary] go
在執行下面的**前請先開啟執行計畫(ctrl+m)和開啟統計io的語句:set statistics io on
在第乙個例子裡面,我們將使用在where子句中的一列來查詢。第乙個查詢中where子句的索引使用第二列(col3),第二個查詢使用第一列(col2)。注意這裡使用了「dbcc dropcleanbuffers」,用於確保沒有快取帶來的影響,**如下:
dbcc dropcleanbuffers
goselect * from dbo.table1 wherecol3=88
godbcc dropcleanbuffers
goselect * from dbo.table1 wherecol2=88
go執行後檢視執行計畫如下:
可以看到,第乙個查詢使用第二列(col3)的索引是在表上執行索引掃瞄,且沒有用到剛才建立的索引。第二個查詢使用了表查詢,使得在表裡只需要使用更少的資源。第乙個查詢讀了6次,而第二個查詢唯讀了4次。
執行查詢後,你應該大概猜到,當表越來越大的時候,效能優勢就顯現出來了。
在下乙個例子中,查詢使用同樣的where子句,但增加了乙個inner join 關聯另外乙個表。第乙個查詢的where子句使用col3,並使用col2來關聯表。
第二個查詢的where子句使用col2,並使用col3來關聯表。
同樣,先執行dbcc dropcleanbuffers來確保快取已經清空。**如下:
dbcc dropcleanbuffers
go
select *
from dbo.table1 inner join
dbo.table2 on dbo.table1.col2 = dbo.table2.col1
where dbo.table1.col3=255
go
dbcc dropcleanbuffers
go
select *
from dbo.table1 inner join
dbo.table2 on dbo.table1.col3 = dbo.table2.col1
where dbo.table1.col2=255
go執行計畫如下:
從執行計畫可以看到,當用於關聯表的列也在索引中,但不是第一列時,會執行索引掃瞄。第二個查詢中索引的第一列來關列,會使用索引查詢。從io來看,同樣索引查詢的讀次數會更小。
從這些例子中,可以看到索引列的順序對錶的查詢也有影響。當建立索引時,先確認你總是對盡可能小的集合進行操作,這意味著索引能從where子句中的列開始。另外,對order by子句中的列和select中的列建立覆蓋索引也有助於提高查詢效能。這樣可以不用在查詢時執行書籤查詢。
在前面提到的,增加太多索引將引起insert/update/delete時對這些索引列的修改。所以,找到平衡點才是最重要的。
SQL Server 索引列的順序 真的沒關係嗎
翻譯自 當設定表的索引時,在效能上有乙個微妙的平衡 太多的索引將影響你的insert update delete操作。但是索引不足又將影響你的select操作。本文將著眼於索引的列順序和如何影響查詢計畫及效能。示例sqlserver表和資料集 tablecreation logic create t...
SQL Server 索引列的順序 真的沒關係嗎
翻譯自 當設定表的索引時,在效能上有乙個微妙的平衡 太多的索引將影響你的insert update delete操作。但是索引不足又將影響你的select操作。本文將著眼於索引的列順序和如何影響查詢計畫及效能。示例sqlserver表和資料集 tablecreation logic create t...
SQL Server 索引列的順序 真的沒關係嗎
原文 sql server 索引列的順序 真的沒關係嗎 翻譯自 當設定表的索引時,在效能上有乙個微妙的平衡 太多的索引將影響你的insert update delete操作。但是索引不足又將影響你的select操作。本文將著眼於索引的列順序和如何影響查詢計畫及效能。示例sqlserver表和資料集 ...