單列索引
獨(dú)立的列
例如,select actor_id from actor where actor_id+1=5;
這個(gè)查詢無(wú)法使用actor_id列的索引。
下面是另一個(gè)常見(jiàn)的錯(cuò)誤:
select ... where TO_DATS(CURRENT_DATA) - TO_DAYS(date_col ) <=10;
列不能是函數(shù)的一部分。
前綴索引和索引選擇性
- 索引的選擇性:不重復(fù)的索引值(也稱為基數(shù))和數(shù)據(jù)表的記錄總數(shù)(#T)的比值,范圍從1/T到1之間。選擇性越高則查詢效率越高,因?yàn)檫x擇性高的索引可以讓Mysql在查找時(shí)過(guò)濾掉更多的行。唯一索引的選擇性是1,這是最好的索引選擇性,性能也是最好的。
- 對(duì)于BLOB、TEXT或者很長(zhǎng)的VARCHAR類型的列,必須使用前綴索引,因?yàn)镸ySQL不允許索引這些列的完整長(zhǎng)度。
- 前綴的“基數(shù)”應(yīng)該接近于完整列的“基數(shù)”。
如何選取適合的前綴長(zhǎng)度?
1.創(chuàng)建模擬數(shù)據(jù)
? ? ? ?數(shù)據(jù)分布不是真實(shí)分布,對(duì)練習(xí)來(lái)說(shuō)并不重要。我們以城市出現(xiàn)的次數(shù)決定該城市的常見(jiàn)與否,出現(xiàn)次數(shù)最多表示該城市最常見(jiàn)。
2.找到最常見(jiàn)的
select count(*) as cnt,city from city_demo group by city order by cnt desc;
3.查找最頻繁出現(xiàn)的城市前綴,先從1個(gè)前綴字幕開(kāi)始:
select count(*) as cnt , left(city,1) as pref from city_demo group by pref order by cnt desc ;
每個(gè)前綴都比原來(lái)的城市出現(xiàn)的次數(shù)更多,因此唯一前綴比唯一城市要少
4.增加前綴長(zhǎng)度
直到這個(gè)前綴的選擇性接近完整列的選擇性。
兩個(gè)前綴:
三個(gè)前綴:
四個(gè)前綴:
發(fā)現(xiàn)前綴為3的時(shí)候,選擇性最接近完整列,所以說(shuō)以列的前三個(gè)字符來(lái)做索引是最合適的。索引體積小且查詢速度快。
選取前綴的另一個(gè)辦法
計(jì)算合適的前綴長(zhǎng)度的另一個(gè)辦法就是計(jì)算完整列的選擇性,并使前綴的選擇性接近于完整列的選擇性。
如:
select count(distinct city)/count(*) from city_demo
完整列的選擇性是0.15,可以在一個(gè)查詢中針對(duì)不同前綴長(zhǎng)度進(jìn)行計(jì)算
select count(distinct city)/count(*) as orginal,
count(distinct left(city,1))/count(*) as sel1,
count(distinct left(city,2))/count(*) as sel2,
count(distinct left(city,3))/count(*) as sel3,
count(distinct left(city,4))/count(*) as sel4,
count(distinct left(city,5))/count(*) as sel5
from city_demo
前綴為3的時(shí)候最接近完整列的選擇性,再增加前綴長(zhǎng)度,選擇性提升的幅度已經(jīng)很小了。
如何創(chuàng)建前綴索引
alter table city_demo add key (city(3));
前綴索引是一種能使索引更小、更快的有效辦法,但另一方面也有缺點(diǎn):mysql無(wú)法使用前綴索引做order by和group by,也無(wú)法使用前綴索引做覆蓋掃描。
應(yīng)用場(chǎng)景
存儲(chǔ)網(wǎng)站會(huì)話時(shí),需要在一個(gè)很長(zhǎng)的十六進(jìn)制字符串上創(chuàng)建索引。此時(shí)如果采用長(zhǎng)度為8的前綴索引通常能顯著地提升性能,且對(duì)上層應(yīng)用完全透明。
后綴索引
字符串反轉(zhuǎn)后做前綴索引