前言:
索引對于數(shù)據(jù)庫的意義重大。尤其是對于海量數(shù)據(jù)的大表。有索引和沒有索引的速度就像法拉利和三輪車。那么有這么好的工具,學習索引和使用索引那就變成了理所當然的事情了。下面我就以MYSQL數(shù)據(jù)庫為例。介紹下索引的三個方面

什么是索引?為什么要用索引?
索引其實也是一張表。它存儲的是索引的值和對應表中的物理位置。他能幫助數(shù)據(jù)庫快速的找到想要找的數(shù)據(jù)。不同的索引只是存儲的數(shù)據(jù)的特性不同。不同的索引引擎也只是存儲和搜索策略的不同。本質(zhì)上還是一張表,會占磁盤空間或者內(nèi)存空間。
那么為什么要用索引呢?這個問題就像是在問用漢語詞典的時候為什么要先查音節(jié)表或者部首檢字表?為什么要這么做呢?
因為快!
沒有索引的表用起來就像是翻開漢語字典一頁頁的找你想找的字。效率太慢。
所以索引是我必須要使用的工具
(也有不適合使用索引的場景。后面會講)
怎么使用索引
使用索引之前,我們需要了解,MYSQL 有哪些索引
常見的索引類型有:主鍵索引 唯一索引 普通索引 全文索引 組合索引
- 主鍵索引:即主索引,根據(jù)主鍵pk_clolum(length)建立索引,不允許重復,不允許空值
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');
- 全文索引:用大文本對象的列構(gòu)建的索引
ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col');
- 組合索引:用多個列組合構(gòu)建的索引,這多個列中的值不允許有空值
ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');
下面分別介紹下 5種索引的使用場景
- 主鍵索引應該是最常見的索引,我們在創(chuàng)建表的時候一般都會創(chuàng)建主鍵,并且打上主鍵索引。主鍵上會有非空性,唯一性。常規(guī)的主鍵還會有自增性。當我們在where 條件中指定主鍵為搜索條件時,速度就會非常的快
- 唯一索引一般用于數(shù)據(jù)本身可以保證唯一,并且有經(jīng)常查詢又不常修改的數(shù)據(jù)。比如常見的用戶郵箱,用戶手機號,身份證,銀行卡等。唯一索引的。唯一索引的用處除了能提高查詢效率以外。當表里插入或修改的數(shù)據(jù)在索引中已經(jīng)出現(xiàn)過了,MYSQL就拒絕這一次修改或者插入。這樣就可以避免數(shù)據(jù)出現(xiàn)重復
- 普通索引的使用場景其實就是數(shù)據(jù)不適合使用唯一索引或者全文索引。但是又經(jīng)常會作為條件來查詢或者排序,這個時候就會用到普通索引。常見的會有排序的字段sort 或者用戶的姓名 name
- 全文索引對應的場景比較單一。就是那種大段內(nèi)容存儲,還需要模糊查詢的。當我使用LIKE '%xxxx%'的時候是不走索引的。解決方案就是全文索引。不過需要注意的是模糊查詢帶有全文索引的字段就不能使用LIKE了。需要使用下面的語句來查詢
SELECT * FROM table_name MATCH(ft_index) AGAINST('查詢字符串');
- 組合索引我認為是根據(jù)業(yè)務來。比如一個查詢語句經(jīng)常執(zhí)行。但是字段又不常修改??梢允褂媒M合索引。組合索引比起對多個字段加上單獨的索引來說,更節(jié)約磁盤的空間。因為本身建立索引就對性能有壓力。建立一個組合索引三個字段,比分別建立三個字段的普通索引 開銷要小。
在組合索引這里展開一下。
當我們使用了組合索引的時候,就需要遵循最左前綴原則
什么是最左前綴原則呢?就是在設(shè)置符合索引的時候盡量在被設(shè)置索引的字段查詢范圍和使用頻次做一個排序。比如A字段 比B字段的查詢范圍和頻次更高。就更應該把A字段排到左邊。同理在編寫查詢語句的時候
也應該遵循這個邏輯。
這里假如 有聯(lián)合索引 (a,b,c)三個字段
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é)合上面的例子
可以簡單的理解為當創(chuàng)建(a,b,c)聯(lián)合索引時,相當于創(chuàng)建了(a)單列索引,(a,b)聯(lián)合索引以及 (a,b,c)聯(lián)合索引
那么在編寫sql的時候就應該往能使用索引的方式去靠
還有就是 在組合索引中字段不能有NULL值。如果有NULL怎么查索引的都是無效的
索引的使用也是要講基本法的
什么場景不適合用索引?
- 數(shù)據(jù)過少的表,不需要用索引。因為數(shù)據(jù)較少,MYSQL會將數(shù)據(jù)讀到內(nèi)存里去,有點類似于緩存。這樣查詢速度會非???。不要使用索引
- 經(jīng)常增刪改的字段不要使用索引。因為本身建立索引和維護索引是有開銷的。如果經(jīng)常變化的字段加上索引會拖慢操作的效率
- 不常被作為條件的字段,不要使用索引。不作為條件的字段除了無法通過索引加速以外,還占用磁盤空間。帶來了維護壓力
什么場景適合使用索引?
- 首先當然是主鍵索引。每個表都應該有主鍵索引
- 經(jīng)常作為查詢條件在WHERE或者ORDER BY 語句中出現(xiàn)的列要建立索引
- 查詢中與其他表關(guān)聯(lián)的字段,外鍵關(guān)系建立索引
- 業(yè)務上要防止重復的字段,應該加上唯一索引
- 用于聚合函數(shù)的字段,比如 count(col) sum(col)。應該建立索引
最后,很多朋友會問,我加了索引,但是不知道sql到底有沒有用到索引。這個時候,只需要拿出索引大殺器explain 在你的sql前面就可以了

概要描述:
- id:選擇標識符
- select_type:表示查詢的類型。
- table:輸出結(jié)果集的表
- partitions:匹配的分區(qū)
- type:表示表的連接類型
- possible_keys:表示查詢時,可能使用的索引
- key:表示實際使用的索引
- key_len:索引字段的長度
- ref:列與索引的比較
- rows:掃描出的行數(shù)(估算的行數(shù))
- filtered:按表條件過濾的行百分比
- Extra:執(zhí)行情況的描述和說明
結(jié)語:
其實關(guān)于索引的知識點還有很多很多,我也不是專業(yè)的DBA,只能說是在后端開發(fā)的角度去介紹下會經(jīng)常用到的東西。還有就是數(shù)據(jù)庫不同的引擎,也不完全一樣。所以這篇文章算是拋磚引玉了,希望以前不太關(guān)注小伙伴能重視索引,也就可以了。
如果這篇文章對你有幫助的話,請點個贊。要是能加個關(guān)注就更好了。