我一個(gè)表 students 表,有3個(gè)字段 ,id,name,age 我要查詢 通過 name 和age,在這兩個(gè)字段 是創(chuàng)建 聯(lián)合索引?還是分別在name和age上創(chuàng)建 單列索引呢? 多個(gè)字段查詢什么情況下用聯(lián)合索引 什么時(shí)候分別創(chuàng)建單列索引呢?
1,首先要確定優(yōu)化的目標(biāo),在什么樣的業(yè)務(wù)場(chǎng)景下,表的大小等等。如果表比較小的話,可能都不需要加索引。
2,哪些字段可以建索引,一般都where、order by 或者 group by 后面的字段。
3,記錄修改的時(shí)候需要維護(hù)索引,所以會(huì)有開銷,要衡量建了索引之后的得與失。
學(xué)生表,可以認(rèn)為name的重復(fù)度比較小,而age的重復(fù)度比較大,對(duì)于單列索引來說,比較適合建在重讀度低的列上。
對(duì)于select * from students where name='張三’and age=18; 題主所說的兩種情況
A. name 和 age 各自單獨(dú)建立索引。
一般來說mysql會(huì)選擇其中一個(gè)索引,name的可能性比較大,因?yàn)閙ysq會(huì)統(tǒng)計(jì)每個(gè)索引上的重復(fù)度,選用低重復(fù)度的字段。另外一個(gè)age的索引就不會(huì)用到,但還有維護(hù)索引的開銷,所以age的索引不需要?jiǎng)?chuàng)建。
B. name和age的聯(lián)合索引
這種索引的切合度最好,mysql會(huì)直接選用這個(gè)索引。但相對(duì)單獨(dú)的name索引來說,維護(hù)的成本要大一些,并且索引數(shù)據(jù)占用的存儲(chǔ)空間也要更大一些。
回過來看,有必要使用聯(lián)合索引嗎? 我的看法是沒有必要,因?yàn)閷W(xué)校里可能會(huì)有重名的人,但比較少。用name就可以比較精準(zhǔn)的找到記錄,即使有重復(fù)的也比較少。
什么情況下使用聯(lián)合索引比較好呢? 舉一個(gè)例子,大學(xué)選認(rèn)課老師,需要?jiǎng)?chuàng)建一個(gè)關(guān)系對(duì)應(yīng)表,有2個(gè)字段,student_id 和 teacher_id,想要查詢某個(gè)老師和某個(gè)學(xué)生是否存在師生關(guān)系。
一個(gè)學(xué)生會(huì)選幾十個(gè)老師,一個(gè)老師會(huì)帶幾百個(gè)學(xué)生
如果只為student_id建立索引的情況下,經(jīng)過索引會(huì)選出幾十條記錄,然后在內(nèi)存中where一下,去除其余的老師。
相反如果只為teacher_id建立索引,經(jīng)過索引會(huì)選出幾百條記錄,然后在內(nèi)存中where一下,去除其余的學(xué)生。
兩種情況都不是最優(yōu)的,這個(gè)時(shí)候使用聯(lián)合索引最合適,通過索引直接找到對(duì)應(yīng)記錄。
創(chuàng)建索引實(shí)例:
首先創(chuàng)建一個(gè)表:create table students (id int primary key,name varchar(20),age Int);
創(chuàng)建單個(gè)索引的語法:create index 索引名 on 表名(字段名)
索引名一般是:表名_字段名
給id創(chuàng)建索引:create index students _id on students (id);
創(chuàng)建聯(lián)合索引的語法:create index 索引名 on 表名(字段名1,字段名2)
給name和age創(chuàng)建聯(lián)合索引:create index students _name_age on students (name,age)
MySQL_MySQL 聯(lián)合索引詳解 以及注意事項(xiàng)
聯(lián)合索引又叫復(fù)合索引。對(duì)于復(fù)合索引:Mysql從左到右的使用索引中的字段,一個(gè)查詢可以只使用索引中的一部份,但只能是最左側(cè)部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3種組合進(jìn)行查找,但不支持 b,c進(jìn)行查找 .當(dāng)最左側(cè)字段是常量引用時(shí),索引就十分有效。
兩個(gè)或更多個(gè)列上的索引被稱作復(fù)合索引。
利用索引中的附加列,您可以縮小搜索的范圍,但使用一個(gè)具有兩列的索引 不同于使用兩個(gè)單獨(dú)的索引。復(fù)合索引的結(jié)構(gòu)與電話簿類似,人名由姓和名構(gòu)成,電話簿首先按姓氏對(duì)進(jìn)行排序,然后按名字對(duì)有相同姓氏的人進(jìn)行排序。如果您知 道姓,電話簿將非常有用;如果您知道姓和名,電話簿則更為有用,但如果您只知道名不姓,電話簿將沒有用處。
所以說創(chuàng)建復(fù)合索引時(shí),應(yīng)該仔細(xì)考慮列的順序。對(duì)索引中的所有列執(zhí)行搜索或僅對(duì)前幾列執(zhí)行搜索時(shí),復(fù)合索引非常有用;僅對(duì)后面的任意列執(zhí)行搜索時(shí),復(fù)合索引則沒有用處。
如:建立 姓名、年齡、性別的復(fù)合索引。
create table test(
a int,
b int,
c int,
KEY a(a,b,c)
);
優(yōu): select * from test where a=10 and b>50
差: select * from test where a50
優(yōu): select * from test order by a
差: select * from test order by b
差: select * from test order by c
優(yōu): select * from test where a=10 order by a
優(yōu): select * from test where a=10 order by b
差: select * from test where a=10 order by c
優(yōu): select * from test where a>10 order by a
差: select * from test where a>10 order by b
差: select * from test where a>10 order by c
優(yōu): select * from test where a=10 and b=10 order by a
優(yōu): select * from test where a=10 and b=10 order by b
優(yōu): select * from test where a=10 and b=10 order by c
優(yōu): select * from test where a=10 and b=10 order by a
優(yōu): select * from test where a=10 and b>10 order by b
差: select * from test where a=10 and b>10 order by c

索引原則
1.索引越少越好
原因:主要在修改數(shù)據(jù)時(shí),第個(gè)索引都要進(jìn)行更新,降低寫速度。
2.最窄的字段放在鍵的左邊
3.避免file sort排序,臨時(shí)表和表掃描.