MySql索引之哪些情況適合創(chuàng)建索引

哪些情況適合創(chuàng)建索引

1. 字段的數值有唯一性的限制

業(yè)務上具有唯一特性的字段,即使是組合字段,也必須建成唯一索引。(來源:Alibaba)

說明:不要以為唯一索引影響了 insert 速度各墨,這個速度損耗可以忽略,但提高查找速度是明顯的瘩绒。

2. 頻繁作為 WHERE 查詢條件的字段

某個字段在SELECT語句的 WHERE 條件中經常被使用到猴抹,那么就需要給這個字段創(chuàng)建索引了。尤其是在

數據量大的情況下锁荔,創(chuàng)建普通索引就可以大幅提升數據查詢的效率蟀给。

比如student_info數據表(含100萬條數據),假設我們想要查詢 student_id=123110 的用戶信息阳堕。

3. 經常 GROUP BY 和 ORDER BY 的列

索引就是讓數據按照某種順序進行存儲或檢索跋理,因此當我們使用 GROUP BY 對數據進行分組查詢,或者

使用 ORDER BY 對數據進行排序的時候恬总,就需要 對分組或者排序的字段進行索引 前普。如果待排序的列有多

個,那么可以在這些列上建立 組合索引 壹堰。

4. UPDATE拭卿、DELETE 的 WHERE 條件列

對數據按照某個條件進行查詢后再進行 UPDATE 或 DELETE 的操作,如果對 WHERE 字段創(chuàng)建了索引贱纠,就

能大幅提升效率峻厚。原理是因為我們需要先根據 WHERE 條件列檢索出來這條記錄,然后再對它進行更新或

刪除谆焊。如果進行更新的時候惠桃,更新的字段是非索引字段,提升的效率會更明顯辖试,這是因為非索引字段更

新不需要對索引進行維護辜王。

5.DISTINCT 字段需要創(chuàng)建索引

有時候我們需要對某個字段進行去重,使用 DISTINCT剃执,那么對這個字段創(chuàng)建索引誓禁,也會提升查詢效率。

比如肾档,我們想要查詢課程表中不同的 student_id 都有哪些摹恰,如果我們沒有對 student_id 創(chuàng)建索引辫继,執(zhí)行

SQL 語句:

SELECT DISTINCT(student_id) FROM `student_info`;

運行結果(600637 條記錄,運行時間 0.683s ):

如果我們對 student_id 創(chuàng)建索引俗慈,再執(zhí)行 SQL 語句:

SELECT DISTINCT(student_id) FROM `student_info`;

運行結果(600637 條記錄姑宽,運行時間 0.010s ):

你能看到 SQL 查詢效率有了提升,同時顯示出來的 student_id 還是按照 遞增的順序 進行展示的闺阱。這是因

為索引會對數據按照某種順序進行排序炮车,所以在去重的時候也會快很多。

6. 多表 JOIN 連接操作時酣溃,創(chuàng)建索引注意事項

首先瘦穆, 連接表的數量盡量不要超過 3 張 ,因為每增加一張表就相當于增加了一次嵌套的循環(huán)赊豌,數量級增

長會非晨富颍快,嚴重影響查詢的效率碘饼。

其次熙兔, 對 WHERE 條件創(chuàng)建索引 ,因為 WHERE 才是對數據條件的過濾艾恼。如果在數據量非常大的情況下住涉,

沒有 WHERE 條件過濾是非常可怕的钠绍。

最后舆声, 對用于連接的字段創(chuàng)建索引 ,并且該字段在多張表中的 類型必須一致 五慈。比如 course_id 在

student_info 表和 course 表中都為 int(11) 類型纳寂,而不能一個為 int 另一個為 varchar 類型。

舉個例子泻拦,如果我們只對 student_id 創(chuàng)建索引毙芜,執(zhí)行 SQL 語句:

image.png

運行結果(1 條數據,運行時間 0.189s ):

這里我們對 name 創(chuàng)建索引争拐,再執(zhí)行上面的 SQL 語句腋粥,運行時間為 0.002s 。

7. 使用列的類型小的創(chuàng)建索引

8. 使用字符串前綴創(chuàng)建索引

創(chuàng)建一張商戶表架曹,因為地址字段比較長隘冲,在地址字段上建立前綴索引

create table shop(address varchar(120) not null);
alter table shop add index(address(12));

問題是,截取多少呢绑雄?截取得多了展辞,達不到節(jié)省索引存儲空間的目的;截取得少了万牺,重復內容太多罗珍,字

段的散列度(選擇性)會降低洽腺。怎么計算不同的長度的選擇性呢?

先看一下字段在全部數據中的選擇度:

select count(distinct address) / count(*) from shop;

通過不同長度去計算覆旱,與全表的選擇性對比:

公式:

count(distinct left(列名, 索引長度))/count(*)

例如:

select count(distinct left(address,10)) / count(*) as sub10, -- 截取前10個字符的選擇度
count(distinct left(address,15)) / count(*) as sub11, -- 截取前15個字符的選擇度
count(distinct left(address,20)) / count(*) as sub12, -- 截取前20個字符的選擇度
count(distinct left(address,25)) / count(*) as sub13 -- 截取前25個字符的選擇度
from shop;

引申另一個問題:索引列前綴對排序的影響

拓展:Alibaba《Java開發(fā)手冊》

【 強制 】在 varchar 字段上建立索引時蘸朋,必須指定索引長度,沒必要對全字段建立索引扣唱,根據實際文本

區(qū)分度決定索引長度藕坯。

說明:索引的長度與區(qū)分度是一對矛盾體,一般對字符串類型數據噪沙,長度為 20 的索引炼彪,區(qū)分度會 高達

90% 以上 ,可以使用 count(distinct left(列名, 索引長度))/count(*)的區(qū)分度來確定正歼。

9. 區(qū)分度高(散列性高)的列適合作為索引

10. 使用最頻繁的列放到聯合索引的左側

這樣也可以較少的建立一些索引霹购。同時,由于"最左前綴原則"朋腋,可以增加聯合索引的使用率。

11. 在多個字段都要創(chuàng)建索引的情況下膜楷,聯合索引優(yōu)于單值索引

28.哪些情況不適合創(chuàng)建索引

1. 在where中使用不到的字段旭咽,不要設置索引

2. 數據量小的表最好不要使用索引

結論:在數據表中的數據行數比較少的情況下,比如不到 1000 行赌厅,是不需要創(chuàng)建索引的穷绵。

3. 有大量重復數據的列上不要建立索引

舉例1:要在 100 萬行數據中查找其中的 50 萬行(比如性別為男的數據),一旦創(chuàng)建了索引特愿,你需要先

訪問 50 萬次索引仲墨,然后再訪問 50 萬次數據表,這樣加起來的開銷比不使用索引可能還要大揍障。

舉例2:假設有一個學生表目养,學生總數為 100 萬人,男性只有 10 個人毒嫡,也就是占總人口的 10 萬分之 1癌蚁。

學生表 student_gender 結構如下。其中數據表中的 student_gender 字段取值為 0 或 1兜畸,0 代表女性努释,1 代

表男性。


如果我們要篩選出這個學生表中的男性咬摇,可以使用:

運行結果(10 條數據伐蒂,運行時間 0.696s ):

結論:當數據重復度大,比如 高于 10% 的時候肛鹏,也不需要對這個字段使用索引逸邦。

4. 避免對經常更新的表創(chuàng)建過多的索引

5. 不建議用無序的值作為索引

例如身份證恩沛、UUID(在索引比較時需要轉為ASCII,并且插入時可能造成頁分裂)昭雌、MD5复唤、HASH、無序長字

符串等烛卧。

6. 刪除不再使用或者很少使用的索引

7. 不要定義冗余或重復的索引

① 冗余索引

舉例:建表語句如下

CREATE TABLE person_info(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
birthday DATE NOT NULL,
phone_number CHAR(11) NOT NULL,
country varchar(100) NOT NULL,
PRIMARY KEY (id),
KEY idx_name_birthday_phone_number (name(10), birthday, phone_number),
KEY idx_name (name(10))
);

我們知道佛纫,通過 idx_name_birthday_phone_number 索引就可以對 name 列進行快速搜索,再創(chuàng)建一

個專門針對 name 列的索引就算是一個 冗余索引 总放,維護這個索引只會增加維護的成本呈宇,并不會對搜索有

什么好處。

② 重復索引

另一種情況局雄,我們可能會對某個列 重復建立索引 甥啄,比方說這樣:

CREATE TABLE repeat_index_demo (
col1 INT PRIMARY KEY,
col2 INT,
UNIQUE uk_idx_c1 (col1),
INDEX idx_c1 (col1)
);

我們看到,col1 既是主鍵炬搭、又給它定義為一個唯一索引蜈漓,還給它定義了一個普通索引,可是主鍵本身就

會生成聚簇索引宫盔,所以定義的唯一索引和普通索引是重復的融虽,這種情況要避免。

歡迎共同進步:
QQ群:1007576722
https://huchao.blog.csdn.net/article/details/124220802?spm=1001.2014.3001.5502

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末灼芭,一起剝皮案震驚了整個濱河市有额,隨后出現的幾起案子,更是在濱河造成了極大的恐慌彼绷,老刑警劉巖巍佑,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異寄悯,居然都是意外死亡萤衰,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門猜旬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腻菇,“玉大人,你說我怎么就攤上這事昔馋〕锿拢” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵秘遏,是天一觀的道長丘薛。 經常有香客問我,道長邦危,這世上最難降的妖魔是什么洋侨? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任舍扰,我火速辦了婚禮,結果婚禮上希坚,老公的妹妹穿的比我還像新娘边苹。我一直安慰自己,他們只是感情好裁僧,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布个束。 她就那樣靜靜地躺著,像睡著了一般聊疲。 火紅的嫁衣襯著肌膚如雪茬底。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天获洲,我揣著相機與錄音阱表,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的牲距。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼烂叔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了固歪?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤胯努,失蹤者是張志新(化名)和其女友劉穎牢裳,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體叶沛,經...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡蒲讯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了灰署。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片判帮。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖溉箕,靈堂內的尸體忽然破棺而出晦墙,到底是詐尸還是另有隱情,我是刑警寧澤肴茄,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布晌畅,位于F島的核電站,受9級特大地震影響寡痰,放射性物質發(fā)生泄漏抗楔。R本人自食惡果不足惜棋凳,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望连躏。 院中可真熱鬧剩岳,春花似錦、人聲如沸入热。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽才顿。三九已至莫湘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間郑气,已是汗流浹背幅垮。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留尾组,地道東北人忙芒。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像讳侨,于是被迫代替她去往敵國和親呵萨。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內容