索引(Index)是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)迹卢,即索引是數(shù)據(jù)結(jié)構(gòu)蝎毡。MySQL索引的建立對于MySQL的高效運(yùn)行是很重要的挣轨,索引可以大大提高M(jìn)ySQL的檢索速度宵溅。
一、索引的用法
1. 創(chuàng)建索引
普通索引
這是最基本的索引類型肿轨,而且它沒有唯一性之類的限制寿冕,通常有三種方式可以創(chuàng)建:
- 直接基于表創(chuàng)建:
CREATE INDEX indexName ON table_name(column_name(length));
- 修改表結(jié)構(gòu)創(chuàng)建:
ALTER table table_name ADD INDEX index_name(column_name);
- 創(chuàng)建表時(shí)指定:
CREATE TABLE table_name(
ID INT NOT NULL,
...
INDEX [index_name] (column_name(length))
);
唯一索引
它與前面的普通索引類似,不同的就是:索引列的值必須唯一椒袍,但允許有空值驼唱。如果是組合索引,則列值的組合必須唯一驹暑。創(chuàng)建唯一索引有三種方法:
- 直接基于表創(chuàng)建:
CREATE UNIQUE INDEX indexName ON table_name(column_name(length));
- 修改表結(jié)構(gòu)創(chuàng)建:
ALTER table table_name ADD UNIQUE index_name(column_name);
- 創(chuàng)建表時(shí)指定:
CREATE TABLE table_name(
ID INT NOT NULL,
...
UNIQUE [index_name] (column_name(length))
);
主鍵索引
主鍵是一種唯一性索引玫恳,但它必須指定為“PRIMARY KEY”,每個表只能有一個主鍵优俘,通常是自增的ID京办,大部分在創(chuàng)建表的時(shí)候指定。它不能用CREATE INDEX語句創(chuàng)建帆焕,共有兩種創(chuàng)建方式惭婿。
- 創(chuàng)建表時(shí)指定:
CREATE TABLE table_name(
ID INT NOT NULL,
...
PRIMARY KEY (column_name(length))
);
- 修改表結(jié)構(gòu)創(chuàng)建:
ALTER table table_name ADD PRIMARY KEY (column_name);
主鍵索引由于每個表中只有一個,所以不需要指定索引名叶雹。主鍵可用自動生成财饥,比如INT字段,可以用AUTO_INCREMENT來自動生成折晦。
2. 刪除索引
- 直接刪除
DROP INDEX index_name ON table_name;
- 修改表結(jié)構(gòu)刪除
ALTER TABLE table_name DROP INDEX index_name;
ALTER TABLE table_name DROP PRIMARY KEY;
3. 查看索引
SHOW INDEX FROM table_name;
二佑力、索引的利弊權(quán)衡
1. 索引的好處
提高數(shù)據(jù)檢索的效率。
在數(shù)據(jù)庫中表的某個字段創(chuàng)建索引筋遭,所帶來的最大益處就是將該字段作為檢索條件時(shí)可以極大地提高檢索效率打颤,加快檢索時(shí)間暴拄,降低檢索過程中須要讀取的數(shù)據(jù)量。降低數(shù)據(jù)的排序成本编饺。
每個索引中的數(shù)據(jù)都是按照索引鍵鍵值進(jìn)行排序后存放的乖篷。如果排序字段和索引鍵字段剛好一致,則取得數(shù)據(jù)后就不用排序了透且,因?yàn)楦鶕?jù)索引取得的數(shù)據(jù)已經(jīng)滿足客戶的排序要求撕蔼。分組操作是要先進(jìn)行排序然后分組的,如果分組字段也剛好和索引鍵字段一致秽誊,同樣可以利用索引已經(jīng)排好序的這個特性鲸沮,省略掉分組中的排序操作。排序分組操作主要消耗的是內(nèi)存和 CPU 資源锅论,如果能夠在進(jìn)行排序分組操作中利用好索引讼溺,將會極大地降低CPU資源的消耗。
2. 索引的弊端
確實(shí)最易,索引能夠極大地提高數(shù)據(jù)檢索效率怒坯,也能夠改善排序分組操作的性能,但有不能忽略的一個問題就是索引是完全獨(dú)立于基礎(chǔ)數(shù)據(jù)之外的一部分?jǐn)?shù)據(jù)藻懒。
如果創(chuàng)建了索引剔猿,則MySQL在更新表的同時(shí),都需要更新索引數(shù)據(jù)嬉荆,調(diào)整因?yàn)楦聨礞I值變化的索引信息归敬。而如果沒有創(chuàng)建索引,MySQL要做的僅僅是更新表中的信息鄙早。這樣汪茧,最明顯的資源消耗就是增加了更新所帶來的 IO 量和調(diào)整索引所致的計(jì)算量。此外蝶锋,索引需要占用存儲空間,而且隨著表中數(shù)據(jù)量的增加什往,索引所占用的空間也會不斷增加扳缕,所以索引還會帶來存儲空間資源消耗的增加。
3. 索引的選擇
- 較頻繁的作為查詢條件的字段應(yīng)該創(chuàng)建索引别威。
- 唯一性太差的字段不適合單獨(dú)創(chuàng)建索引躯舔,即使頻繁作為查詢條件。
如狀態(tài)字段省古、類型字段等這些字段中存放的數(shù)據(jù)可能總共就是那么幾個或幾十個值重復(fù)使用粥庄,每個值都會存在于成千上萬或更多的記錄中。對于這類字段豺妓,完全沒有必要創(chuàng)建單獨(dú)的索引惜互。 - 更新非常頻繁的字段不適合創(chuàng)建索引布讹。
引中的字段被更新的時(shí)候,不僅要更新表中的數(shù)據(jù)训堆,還要更新索引數(shù)據(jù)描验,以確保索引信息是準(zhǔn)確的。這個問題致使IO 訪問量較大增加坑鱼,不僅僅影響了更新 Query 的響應(yīng)時(shí)間膘流,還影響了整個存儲系統(tǒng)的資源消耗,加大了整個存儲系統(tǒng)的負(fù)載鲁沥。 - 不會出現(xiàn)在 WHERE 子句中的字段不該創(chuàng)建索引呼股。