SQL Server 索引列的順序 真的沒關係嗎

2021-08-27 00:25:08 字數 3555 閱讀 6337

翻譯自:

當設定表的索引時,在效能上有乙個微妙的平衡:太多的索引將影響你的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表和資料集 ...