本文是MySQL(三)|《千萬級(jí)大數(shù)據(jù)查詢優(yōu)化》第一篇:創(chuàng)建高性能的索引的一個(gè)補(bǔ)充。
主要包括如下幾點(diǎn):
- 關(guān)于
sex列創(chuàng)建索引的處理
sex可以理解為那種選擇性不高,但是可能很多查詢都會(huì)用到的列??紤]到使用的頻率,還是建議在創(chuàng)建不同組合索引的時(shí)候?qū)⑺鳛榍熬Y。
但是根據(jù)經(jīng)驗(yàn)法則(將選擇性最高的列放到索引最前列)不是說不應(yīng)該在選擇性低的列上創(chuàng)建索引嗎?那為什么這里要將sex列字段作為索引的前綴列?這里有兩個(gè)理由:
第一點(diǎn),幾乎所有的查詢都會(huì)用到它;
第二點(diǎn),索引中加上這一列也沒有壞處,即使查詢沒有使用sex列也可以通過一些“訣竅”繞過,這個(gè)訣竅就是:如果每個(gè)查詢不限制性別,那么可以通過在查詢條件中新增AND SEX IN('m', 'f')來讓MySQL選擇該索引。這樣寫并不會(huì)過濾任何行,和沒有這個(gè)條件時(shí)返回的結(jié)果相同。但是必須加上這個(gè)列的條件,MySQL才能夠匹配索引的最左前綴。 - 避免創(chuàng)建冗余和重復(fù)索引
重復(fù)索引的概念很好理解,我們也不會(huì)出現(xiàn)創(chuàng)建兩個(gè)idx_ab、idx_ab的索引,很多時(shí)候是在不經(jīng)意間創(chuàng)建的。關(guān)于冗余,就得做一個(gè)說明啦。舉例如下,我在新建一個(gè)表時(shí),要把ID設(shè)置為主鍵,必須保證它是唯一的,還要在它身上加上索引:
create table test(
ID INT NOT NULL PRIMARY KEY,
A INT NOT NULL,
B INT NOT NULL,
UNIQUE(ID),
INDEX(ID),
)ENGINE-InnoDB;
因?yàn)镸ySQL的唯一限制和主鍵限制都是通過索引實(shí)現(xiàn)的,所以實(shí)際上上面對(duì)ID創(chuàng)建了3個(gè)重復(fù)的索引。
如果創(chuàng)建了索引idx_ab,再創(chuàng)建索引idx_a就是冗余索引,創(chuàng)建索引idx_b或idx_ba都不是冗余索引。(這個(gè)冗余只是對(duì)B-Tree索引來說的)
- 找出未使用的索引,進(jìn)行刪除
除了冗余索引和重復(fù)索引,可能還會(huì)有一些服務(wù)器永遠(yuǎn)不用的索引,這種索引完全是累贅,需要?jiǎng)h除。有很多工具可以幫助定位未使用的索引。 - 沒有萬金油般的索引,也沒有放之四海而皆準(zhǔn)的經(jīng)驗(yàn)法則
經(jīng)常在網(wǎng)上聽到一些經(jīng)驗(yàn)法則,包括我在上一篇文章中也提到過一些法則:
“在多列索引中將選擇性最高的列放在第一列”、“應(yīng)該為where子句中出現(xiàn)的所有列創(chuàng)建索引”...所有的法則都只是在特定場(chǎng)景才有效果。 - 定期維護(hù)索引和表
維護(hù)表有三個(gè)主要的目的:找到并修復(fù)損害的表,維護(hù)準(zhǔn)確的索引統(tǒng)計(jì)信息,減少碎片。 - 對(duì)索引的優(yōu)點(diǎn)做一個(gè)總結(jié)
索引的優(yōu)點(diǎn):
1)索引大大減少了服務(wù)器需要掃描的數(shù)據(jù)量。
2)索引可以幫助服務(wù)器避免排序和臨時(shí)表。
3)索引可以將隨機(jī)I/O變?yōu)轫樞騃/O。