怎樣才能充分利用SQL索引

2021-07-14 04:02:11 字數 4947 閱讀 2769

背景:目前web的普及太快,很多**都會因為大流量的資料而發生伺服器習慣性宕機,乙個查詢語句只能適用於一定的網路環境.沒有優化的查詢當遇上大資料量時就不適用了.

本文主旨:討論什麼情況下能利用上索引.

索引:建立索引可以根據查詢業務的不同分為兩種:單一列的索引,聯合索引. 顧名思義,單一列索引就是指在表的某一列上建立索引,聯合索引是在多個列上聯合建立索引.

優缺點比較:

1):索引所占用空間:單一列索引相對要小.

3):索引對insert,update,delete的影響程式:單一列索引要相對低. 

4):在多條件查詢時,聯合索引效率要高. 

索引的使用範圍:單一列索引可以出現在where 條件中的任何位置,而聯合索引需要按一定的順序來寫. 

本文所用測試軟體環境如下:sql05  

demo:建立乙個人員表,包含人員id,姓名.在人員id上建立乙個聚集索引,在first_name和last_name上建立乙個聯合

索引.  

create table person (id int, last_name varchar(30), first_name varchar(30))

create unique clustered index person_id on person (id)

create index person_name on person (last_name, first_name)

在上例中,id上建立了聚集索引,下面的查詢都會用了聚集索引. 

where id=1

where id>1

where id<1

where id between 1 and n

where id like '1%'

where id in(1,2,3...)

說明:  id 列出現在條件中的位置並不一定要求第一列,不受位置影響.

不過下面的查詢方式則不會用上聚集索引.

where person_id +1=n

where person_id like '%5'

where person_id like '%5%'

where person_id abs(15)

聯合索引列比起單一列索引最大的好處在於,對於多條件的查詢它比起單一列索引更加精確.拿上面的人員表來說吧,如果

要查詢乙個人的全名,只知道first_name是很難馬上找到這個人的全名的,如果知道first_name和last_name則會非常容易找到.下面根據不同的條件與輸出列順序說明索引的應用.

第一種情況:

--條件和輸出列和索引列順序相同

select last_name,first_name from person where last_name='1' and first_name='1'

stmttext

index seek(object:([bdg_web_vaction].[dbo].[person].[person_name]), 

seek:([bdg_web_vaction].[dbo].[person].[last_name]=[@1] 

and [bdg_web_vaction].[dbo].[person].[first_name]=[@2]) ordered forward)

結果:利用person_name聯合索引查詢

第二種情況:

--條件列與索引列順序不同,但輸出列相同

select last_name,first_name from person where first_name='1' and last_name='1'

stmttext

index seek(object:([bdg_web_vaction].[dbo].[person].[person_name]), 

seek:([bdg_web_vaction].[dbo].[person].[last_name]=[@2] and [bdg_web_vaction].

[dbo].[person].[first_name]=[@1]) ordered forward)

結果:利用person_name聯合索引查詢

第三種情況:

--條件列與輸出列與索引列的順序都不相同

select first_name,last_name from person where first_name='1' and last_name='1'

index seek(object:([bdg_web_vaction].[dbo].[person].[person_name]), 

seek:([bdg_web_vaction].[dbo].[person].

[last_name]=[@2] and [bdg_web_vaction].[dbo].[person].[first_name]=[@1]) ordered forward) 

結果:利用person_name聯合索引查詢

第四種情況:

--條件列在first_name和last_name中間加入另外乙個條件

select id, first_name,last_name from person where first_name='1' and  

id=1

and last_name='1'

clustered index seek(object:([bdg_web_vaction].[dbo].[person].[person_id]),

seek:([bdg_web_vaction].[dbo].[person].[id]=convert_implicit(int,[@2],0)),  

where:([bdg_web_vaction].[dbo].[person].[first_name]=[@1] and [bdg_web_vaction].[dbo].[person].[las

結果:不能利用person_name聯合索引查詢

第五種情況:

--在輸出列中分開first_name和last_name

select  first_name,

id,last_name from person where first_name='1' and last_name='1'

index seek(object:([bdg_web_vaction].[dbo].[person].[person_name]),

seek:([bdg_web_vaction].[dbo].[person].

[last_name]=[@2] and [bdg_web_vaction].[dbo].[person].[first_name]=[@1])

ordered forward) 

結果:利用person_name聯合索引查詢

第六種情況:

條件列沒有出現聯合索引的第一列

select  first_name,id,last_name from person where first_name='1'

select  first_name,last_name from person where first_name='1'

select  last_name ,first_name from person where first_name='1'

index scan(object:([bdg_web_vaction].[dbo].[person].[person_name]),

where:([bdg_web_vaction].[dbo].[person].[first_name]=[@1]))

結果:不能利用person_name聯合索引.

第七種情況:

--條件列出現聯合索引的第一列

select  first_name,id,last_name from person where last_name='1'

select  first_name,last_name from person where last_name='1'

select  last_name ,first_name from person where last_name='1'

index seek(object:([bdg_web_vaction].[dbo].[person].[person_name]),

seek:([bdg_web_vaction].[dbo].[person].[last_name]=[@1]) ordered forward) 

結果:利用person_name聯合索引查詢

聯合索引使用總結:

1):查詢條件中出現聯合索引第一列,或者全部,則能利用聯合索引.

2):條件列中只要條件相連在一起,以本文例子來說就是:

last_name='1' and first_name='1'

與first_name='1' and last_name='1' 

,無論前後,都會利用上聯合索引.

3):查詢條件中沒有出現聯合索引的第一列,而出現聯合索引的第二列,或者第三列,都不會利用聯合索引查詢. 

單一列索引的應用總結:

1):只要條件列中出現索引列,無論在什麼位置,都能利用索引查詢.

兩者的共同點:

1):要想利用索引,都要符合sarg標準.

2) :都是為了提高查詢速度.

3):都需要額外的系統開銷,磁碟空間.

補充說明: stmttext資訊來產生,在查詢語句前面加上:set statistics profile on.可以通過執行它,來觀察你的查詢是否合理,這樣才能真正做到優化.

總結:即使表上建立了索引,但如果查詢語句寫的不科學的話(不符合sarg標準),也於事無補,要根據表索引情況來優化查詢語句,如沒有合適的索引可用,則要建立相應索引.

怎樣才能充分利用SQL索引

怎樣才能充分利用sql索引 背景 目前web的普及太快,很多 都會因為大流量的資料而發生伺服器習慣性宕機,乙個查詢語句只能適用於一定的網路環境.沒有優化的查詢當遇上大資料量時就不適用了.本文主旨 討論什麼情況下能利用上索引.索引 建立索引可以根據查詢業務的不同分為兩種 單一列的索引,聯合索引.顧名思...

怎樣才能充分利用SQL索引

怎樣才能充分利用sql索引 背景 目前web的普及太快,很多 都會因為大流量的資料而發生伺服器習慣性宕機,乙個查詢語句只能適用於一定的網路環境.沒有優化的查詢當遇上大資料量時就不適用了.本文主旨 討論什麼情況下能利用上索引.索引 建立索引可以根據查詢業務的不同分為兩種 單一列的索引,聯合索引.顧名思...

怎樣才能充分利用SQL索引

怎樣才能充分利用sql索引 背景 目前web的普及太快,很多 都會因為大流量的資料而發生伺服器習慣性宕機,乙個查詢語句只能適用於一定的網路環境.沒有優化的查詢當遇上大資料量時就不適用了.本文主旨 討論什麼情況下能利用上索引.索引 建立索引可以根據查詢業務的不同分為兩種 單一列的索引,聯合索引.顧名思...