前言:
索引對(duì)于數(shù)據(jù)庫(kù)的意義重大螃宙。尤其是對(duì)于海量數(shù)據(jù)的大表蛮瞄。有索引和沒有索引的速度就像法拉利和三輪車。那么有這么好的工具谆扎,學(xué)習(xí)索引和使用索引那就變成了理所當(dāng)然的事情了挂捅。下面我就以MYSQL數(shù)據(jù)庫(kù)為例。介紹下索引的三個(gè)方面
什么是索引堂湖?為什么要用索引闲先?
索引其實(shí)也是一張表。它存儲(chǔ)的是索引的值和對(duì)應(yīng)表中的物理位置无蜂。他能幫助數(shù)據(jù)庫(kù)快速的找到想要找的數(shù)據(jù)饵蒂。不同的索引只是存儲(chǔ)的數(shù)據(jù)的特性不同。不同的索引引擎也只是存儲(chǔ)和搜索策略的不同酱讶。本質(zhì)上還是一張表退盯,會(huì)占磁盤空間或者內(nèi)存空間。
那么為什么要用索引呢泻肯?這個(gè)問題就像是在問用漢語(yǔ)詞典的時(shí)候?yàn)槭裁匆炔橐艄?jié)表或者部首檢字表渊迁?為什么要這么做呢?
因?yàn)榭欤?br>
沒有索引的表用起來就像是翻開漢語(yǔ)字典一頁(yè)頁(yè)的找你想找的字灶挟。效率太慢琉朽。
所以索引是我必須要使用的工具
(也有不適合使用索引的場(chǎng)景。后面會(huì)講)
怎么使用索引
使用索引之前稚铣,我們需要了解箱叁,MYSQL 有哪些索引
常見的索引類型有:主鍵索引 唯一索引 普通索引 全文索引 組合索引
- 主鍵索引:即主索引墅垮,根據(jù)主鍵pk_clolum(length)建立索引,不允許重復(fù)耕漱,不允許空值
ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col')算色;
- 唯一索引:用來建立索引的列的值必須是唯一的,允許空值
ALTER TABLE 'table_name' ADD UNIQUE index_name('col')螟够;
- 普通索引:用表中的普通列構(gòu)建的索引灾梦,沒有任何限制
ALTER TABLE 'table_name' ADD INDEX index_name('col');
- 全文索引:用大文本對(duì)象的列構(gòu)建的索引
ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col')妓笙;
- 組合索引:用多個(gè)列組合構(gòu)建的索引若河,這多個(gè)列中的值不允許有空值
ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');
下面分別介紹下 5種索引的使用場(chǎng)景
- 主鍵索引應(yīng)該是最常見的索引寞宫,我們?cè)趧?chuàng)建表的時(shí)候一般都會(huì)創(chuàng)建主鍵萧福,并且打上主鍵索引。主鍵上會(huì)有非空性辈赋,唯一性鲫忍。常規(guī)的主鍵還會(huì)有自增性。當(dāng)我們?cè)趙here 條件中指定主鍵為搜索條件時(shí)炭庙,速度就會(huì)非常的快
- 唯一索引一般用于數(shù)據(jù)本身可以保證唯一饲窿,并且有經(jīng)常查詢又不常修改的數(shù)據(jù)煌寇。比如常見的用戶郵箱焕蹄,用戶手機(jī)號(hào),身份證阀溶,銀行卡等腻脏。唯一索引的。唯一索引的用處除了能提高查詢效率以外银锻。當(dāng)表里插入或修改的數(shù)據(jù)在索引中已經(jīng)出現(xiàn)過了永品,MYSQL就拒絕這一次修改或者插入。這樣就可以避免數(shù)據(jù)出現(xiàn)重復(fù)
- 普通索引的使用場(chǎng)景其實(shí)就是數(shù)據(jù)不適合使用唯一索引或者全文索引击纬。但是又經(jīng)常會(huì)作為條件來查詢或者排序鼎姐,這個(gè)時(shí)候就會(huì)用到普通索引。常見的會(huì)有排序的字段sort 或者用戶的姓名 name
- 全文索引對(duì)應(yīng)的場(chǎng)景比較單一更振。就是那種大段內(nèi)容存儲(chǔ)炕桨,還需要模糊查詢的。當(dāng)我使用LIKE '%xxxx%'的時(shí)候是不走索引的肯腕。解決方案就是全文索引献宫。不過需要注意的是模糊查詢帶有全文索引的字段就不能使用LIKE了。需要使用下面的語(yǔ)句來查詢
SELECT * FROM table_name MATCH(ft_index) AGAINST('查詢字符串');
- 組合索引我認(rèn)為是根據(jù)業(yè)務(wù)來实撒。比如一個(gè)查詢語(yǔ)句經(jīng)常執(zhí)行姊途。但是字段又不常修改涉瘾。可以使用組合索引捷兰。組合索引比起對(duì)多個(gè)字段加上單獨(dú)的索引來說立叛,更節(jié)約磁盤的空間。因?yàn)楸旧斫⑺饕蛯?duì)性能有壓力寂殉。建立一個(gè)組合索引三個(gè)字段囚巴,比分別建立三個(gè)字段的普通索引 開銷要小。
在組合索引這里展開一下友扰。
當(dāng)我們使用了組合索引的時(shí)候彤叉,就需要遵循最左前綴原則
什么是最左前綴原則呢?就是在設(shè)置符合索引的時(shí)候盡量在被設(shè)置索引的字段查詢范圍和使用頻次做一個(gè)排序村怪。比如A字段 比B字段的查詢范圍和頻次更高秽浇。就更應(yīng)該把A字段排到左邊。同理在編寫查詢語(yǔ)句的時(shí)候
也應(yīng)該遵循這個(gè)邏輯甚负。
這里假如 有聯(lián)合索引 (a,b,c)三個(gè)字段
SELECT * FROM table_name WHERE a=1;//索引有效
SELECT * FROM table_name WHERE b='xx';//索引無效
SELECT * FROM table_name WHERE a=1 AND b='xx';//索引有效
SELECT * FROM table_name WHERE b='xx' AND a=1;//索引有效
SELECT * FROM table_name WHERE a=1 AND c='hahahaha';//索引有效
SELECT * FROM table_name WHERE b='xx' AND c='hahahaha';//索引無效
SELECT * FROM table_name WHERE a=1 AND b='xx' AND c='hahahaha';//索引有效
所以結(jié)合上面的例子
可以簡(jiǎn)單的理解為當(dāng)創(chuàng)建(a,b,c)聯(lián)合索引時(shí)柬焕,相當(dāng)于創(chuàng)建了(a)單列索引,(a,b)聯(lián)合索引以及 (a,b,c)聯(lián)合索引
那么在編寫sql的時(shí)候就應(yīng)該往能使用索引的方式去靠
還有就是 在組合索引中字段不能有NULL值梭域。如果有NULL怎么查索引的都是無效的
索引的使用也是要講基本法的
什么場(chǎng)景不適合用索引斑举?
- 數(shù)據(jù)過少的表,不需要用索引病涨。因?yàn)閿?shù)據(jù)較少富玷,MYSQL會(huì)將數(shù)據(jù)讀到內(nèi)存里去,有點(diǎn)類似于緩存既穆。這樣查詢速度會(huì)非呈昱常快。不要使用索引
- 經(jīng)常增刪改的字段不要使用索引幻工。因?yàn)楸旧斫⑺饕途S護(hù)索引是有開銷的励两。如果經(jīng)常變化的字段加上索引會(huì)拖慢操作的效率
- 不常被作為條件的字段,不要使用索引囊颅。不作為條件的字段除了無法通過索引加速以外当悔,還占用磁盤空間。帶來了維護(hù)壓力
什么場(chǎng)景適合使用索引踢代?
- 首先當(dāng)然是主鍵索引盲憎。每個(gè)表都應(yīng)該有主鍵索引
- 經(jīng)常作為查詢條件在WHERE或者ORDER BY 語(yǔ)句中出現(xiàn)的列要建立索引
- 查詢中與其他表關(guān)聯(lián)的字段,外鍵關(guān)系建立索引
- 業(yè)務(wù)上要防止重復(fù)的字段奸鬓,應(yīng)該加上唯一索引
- 用于聚合函數(shù)的字段焙畔,比如 count(col) sum(col)。應(yīng)該建立索引
最后串远,很多朋友會(huì)問宏多,我加了索引儿惫,但是不知道sql到底有沒有用到索引。這個(gè)時(shí)候伸但,只需要拿出索引大殺器explain
在你的sql前面就可以了
概要描述:
- id:選擇標(biāo)識(shí)符
- select_type:表示查詢的類型肾请。
- table:輸出結(jié)果集的表
- partitions:匹配的分區(qū)
- type:表示表的連接類型
- possible_keys:表示查詢時(shí),可能使用的索引
- key:表示實(shí)際使用的索引
- key_len:索引字段的長(zhǎng)度
- ref:列與索引的比較
- rows:掃描出的行數(shù)(估算的行數(shù))
- filtered:按表?xiàng)l件過濾的行百分比
- Extra:執(zhí)行情況的描述和說明
結(jié)語(yǔ):
其實(shí)關(guān)于索引的知識(shí)點(diǎn)還有很多很多更胖,我也不是專業(yè)的DBA铛铁,只能說是在后端開發(fā)的角度去介紹下會(huì)經(jīng)常用到的東西。還有就是數(shù)據(jù)庫(kù)不同的引擎却妨,也不完全一樣饵逐。所以這篇文章算是拋磚引玉了,希望以前不太關(guān)注小伙伴能重視索引彪标,也就可以了倍权。
如果這篇文章對(duì)你有幫助的話,請(qǐng)點(diǎn)個(gè)贊捞烟。要是能加個(gè)關(guān)注就更好了薄声。