mysql單列索引是我們使用mysql資料庫中經常會見到的,mysql單列索引和組合索引的區別可能有很多人還不是十分的了解,下面就為您分析兩者的主要區別,供您參考學習。
為了形象地對比兩者,再建乙個表:
create table myindex (
i_testid int not null auto_increment,
vc_name varchar(50) not null,
vc_city varchar(50) not null,
i_age int not null,
i_schoolid int not null,
primary key (i_testid)
);在這 10000 條記錄裡面 7 上 8 下地分布了 5 條 vc_name="erquan" 的記錄,只不過 city,age,school 的組合各不相同。
來看這條t-sql:
select i_testid from myindex where vc_name='erquan' and vc_city='鄭州' and i_age=25;
首先考慮建mysql單列索引:
在vc_name列上建立了索引。執行 t-sql 時,mysql 很快將目標鎖定在了vc_name=erquan 的 5 條記錄上,取出來放到一中間結果集。在這個結果集裡,先排除掉 vc_city 不等於"鄭州"的記錄,再排除 i_age 不等於 25 的記錄,最後篩選出唯一的符合條件的記錄。
雖然在 vc_name 上建立了索引,查詢時mysql不用掃瞄整張表,效率有所提高,但離我們的要求還有一定的距離。同樣的,在 vc_city 和 i_age 分別建立的mysql單列索引的效率相似。
為了進一步榨取 mysql 的效率,就要考慮建立組合索引
。就是將 vc_name,vc_city,i_age 建到乙個索引裡:
alter table myindex add index name_city_age (vc_name(10),vc_city,i_age);
建表時,vc_name 長度為 50,這裡為什麼用 10 呢?因為一般情況下名字的長度不會超過 10,這樣會加速索引查詢速度,還會減少索引檔案的大小,提高 insert 的更新速度。
執行 t-sql 時,mysql 無須掃瞄任何記錄就到找到唯一的記錄。
肯定有人要問了,如果分別在 vc_name,vc_city,i_age 上建立單列索引,讓該錶有 3 個單列索引,查詢時和上述的組合索引效率一樣嗎?大不一樣,
遠遠低於我們的組合索引
。雖然此時有了三個索引,但 mysql 只能用到其中的那個它認為似乎是最有效率的單列索引。
建立這樣的組合索引,其實是相當於分別建立了
(vc_name,vc_city,i_age) ( vc_name,vc_city ) ( vc_name)
這樣的三個組合索引!為什麼沒有 vc_city,i_age 等這樣的組合索引呢?這是因為 mysql 組合索引「
最左字首」
的結果。簡單的理解就是
只從最左面的開始組合
。並不是只要包含這三列的查詢都會用到該組合索引,下面的幾個 t-sql 會用到:
select * from myindex whree vc_name="erquan" and vc_city="鄭州"
select * from myindex whree vc_name="erquan"
而下面幾個則不會用到:
select * from myindex whree i_age=20 and vc_city="鄭州"
select * from myindex whree vc_city="鄭州"
1. 為什麼使用索引
在無索引的情況下,mysql會掃瞄整張表來查詢符合sql條件的記錄,其時間開銷與表中資料量呈正相關。對關係型資料表中的某些欄位建索引可以極大提高查詢速度(當然,不同字段是否selective會導致這些字段建立的索引對查詢速度的提公升幅度不同,而且
索引也並非越多越好,因為寫入或刪除時需要更新索引資訊)。
對於mysql的innodb儲存引擎來說,大部分型別的index均以b-tree資料結構的變種b+tree來儲存(memory型別的表還支援hash型別的索引)。b-tree是資料庫或檔案系統中常用的一種資料結構,它是一種n叉平衡樹,這種樹結構保證了同層節點儲存的key有序,對於某個節點來說,其左子樹儲存的所有key均小於該節點儲存的key,其右子樹儲存的所有key均大於該節點儲存的key。此外,在工程實現上,還結合作業系統的區域性性原理做了很多優化,總之,b-tree的各種特性或優化技巧能保證:1) 查詢磁碟記錄時,讀盤次數最少;2) 任何insert和delete操作對樹結構的影響均很小;3) 樹本身的rebalance操作很高效。
2. mysql使用索引的場景
mysql在以下操作場景下會使用索引:
1) 快速查詢符合where條件的記錄
2) 快速確定候選集。
若where條件使用了多個索引字段,則mysql會優先使用能使候選記錄集規模最小的那個索引,以便盡快淘汰不符合條件的記錄。
3) 如果表中存在幾個字段構成的聯合索引,則查詢記錄時,這個聯合索引的最左字首匹配欄位也會被自動作為索引來加速查詢。
例如,若為某錶建立了3個字段(c1, c2, c3)構成的聯合索引,則(c1), (c1, c2), (c1, c2, c3)均會作為索引,(c2, c3)就不會被作為索引,而(c1, c3)其實只利用到c1索引。
4) 多表做join操作時會使用索引(如果參與join的字段在這些表中均建立了索引的話)
5) 若某字段已建立索引,求該字段的min()或max()時,mysql會使用索引
6) 對建立了索引的字段做sort或group操作時,mysql會使用索引
3. 哪些sql語句會真正利用索引
從mysql官網文件"comparison of b-tree and hash indexes"可知,下面這些型別的sql可能會真正用到索引:
1) b-tree可被用於sql中對列做比較的表示式,如=, >, >=, <, <=及between操作
2) 若like語句的條件是不以萬用字元開頭的常量串,mysql也會使用索引
比如,select * from tbl_name where key_col like 'patrick%'或select * from tbl_name where key_col like 'pat%_ck%'可以利用索引,而select * from tbl_name where key_col like '%patrick%'(以萬用字元開頭)和select * from tbl_name where key_col like other_col(like條件不是常量串)無法利用索引。
對於形如like '%string%'的sql語句,若萬用字元後面的string長度大於3,則mysql會利用turbo boyer-moore algorithm演算法進行查詢。
3) 若已對名為col_name的列建了索引,則形如"col_name is null"的sql會用到索引
4) 對於聯合索引,sql條件中的最左字首匹配欄位會用到索引,示例請參考本文第2節第3條對聯合索引的說明
5) 若sql語句中的where條件不只1個條件,則mysql會進行index merge優化來縮小候選集範圍
MySQL單列索引和組合索引
單列索引,顧名思義也就是只有乙個欄位的索引列。組合索引,又稱復合索引,兩個或更多個列上的索引被稱作復合索引。對於復合索引,他們都遵循左側原則,也是就是說乙個查詢可以只使用復合索引最左側的一部份。例如索引是key index a,b,c 可以支援a a,b a,b,c 3種組合進行查詢,但不支援 b,...
MySQL中的單列索引和組合索引
從資料庫角度看索引 有b 樹索引和hash索引。從物理角度看索引 有聚集索引和非聚集索引。而從邏輯角度看索引 有單列索引和組合索引。單列索引 即乙個索引只包含單個列,乙個表可以有多個單列索引,但這不是組合索引。組合索引 即乙個索包含多個列。注 1.在mysql中執行查詢時,只能使用乙個索引,如果我們...
MySQL單列索引和組合索引的區別介紹
mysql單列索引是我們使用mysql資料庫中經常會見到的,mysql單列索引和組合索引的區別可能有很多人還不是十分的了解,下面就為您分析兩者的主要區別,供您參考學習。為了形象地對比兩者,再建乙個表 create table myindex i testid int not null auto in...