mysql 聯合索引和唯一索引


一般來說.如果有where a=? and b=? and c=? 的語句.
如果表也有DML, 我一般只在a 上建索引.  這也是代價平衡的結果. 一方面 只在a 上建索引那么是
index range scan, 不像聯合索引那樣可以index  unique scan , 我覺得速度差的不多(數據量不大的情況).
另一方面,DML也會更新index,更新三個column肯定比更新一個column慢些. 所以我一般采取折中.只建單列或2列索引.


聯合索引對於查詢
where a=? and b=? and c=?
這樣的語句時,速度比分開的索引要快很多!

我現在有一個應用
幾乎就是按照這種順序來查找記錄的
所以,我就建立了聯合索引
----------------------------------------------------
建立聯合索引之后,也不影響你再在這個字段上面創建普通索引。
索引怎么建立,除了你的程序應用,還應當要考慮到表的活動是否頻繁,
如果是典型的oltp,索引就不要建立太多,位圖索引就不用考慮,
但是dss系統,主要是為了檢索,索引多一點就無所謂

 

聯合索引使用結論:


   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.可以通過運行它,來觀察你的查詢是否合理,這樣才能真正做到優化.

 

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

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

   優缺點比較:

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

   2):索引創建時間:單一列索引相對短.

   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標准),也於事無補,要根據表索引情況來優化查詢語句,如沒有合適的索引可用,則要創建相應索引


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM