9102年都快過完了,你還在亂加索引嗎

前言:

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


什么是索引?為什么要用索引?

索引其實也是一張表。它存儲的是索引的值和對應表中的物理位置。他能幫助數(shù)據(jù)庫快速的找到想要找的數(shù)據(jù)。不同的索引只是存儲的數(shù)據(jù)的特性不同。不同的索引引擎也只是存儲和搜索策略的不同。本質(zhì)上還是一張表,會占磁盤空間或者內(nèi)存空間。
那么為什么要用索引呢?這個問題就像是在問用漢語詞典的時候為什么要先查音節(jié)表或者部首檢字表?為什么要這么做呢?
因為快!
沒有索引的表用起來就像是翻開漢語字典一頁頁的找你想找的字。效率太慢。

所以索引是我必須要使用的工具

(也有不適合使用索引的場景。后面會講)

怎么使用索引

使用索引之前,我們需要了解,MYSQL 有哪些索引
常見的索引類型有:主鍵索引 唯一索引 普通索引 全文索引 組合索引

  1. 主鍵索引:即主索引,根據(jù)主鍵pk_clolum(length)建立索引,不允許重復,不允許空值
ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col');
  1. 唯一索引:用來建立索引的列的值必須是唯一的,允許空值
ALTER TABLE 'table_name' ADD UNIQUE index_name('col');
  1. 普通索引:用表中的普通列構(gòu)建的索引,沒有任何限制
ALTER TABLE 'table_name' ADD INDEX index_name('col');
  1. 全文索引:用大文本對象的列構(gòu)建的索引
ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col');
  1. 組合索引:用多個列組合構(gòu)建的索引,這多個列中的值不允許有空值
ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');

下面分別介紹下 5種索引的使用場景

  1. 主鍵索引應該是最常見的索引,我們在創(chuàng)建表的時候一般都會創(chuàng)建主鍵,并且打上主鍵索引。主鍵上會有非空性,唯一性。常規(guī)的主鍵還會有自增性。當我們在where 條件中指定主鍵為搜索條件時,速度就會非常的快
  2. 唯一索引一般用于數(shù)據(jù)本身可以保證唯一,并且有經(jīng)常查詢又不常修改的數(shù)據(jù)。比如常見的用戶郵箱,用戶手機號,身份證,銀行卡等。唯一索引的。唯一索引的用處除了能提高查詢效率以外。當表里插入或修改的數(shù)據(jù)在索引中已經(jīng)出現(xiàn)過了,MYSQL就拒絕這一次修改或者插入。這樣就可以避免數(shù)據(jù)出現(xiàn)重復
  3. 普通索引的使用場景其實就是數(shù)據(jù)不適合使用唯一索引或者全文索引。但是又經(jīng)常會作為條件來查詢或者排序,這個時候就會用到普通索引。常見的會有排序的字段sort 或者用戶的姓名 name
  4. 全文索引對應的場景比較單一。就是那種大段內(nèi)容存儲,還需要模糊查詢的。當我使用LIKE '%xxxx%'的時候是不走索引的。解決方案就是全文索引。不過需要注意的是模糊查詢帶有全文索引的字段就不能使用LIKE了。需要使用下面的語句來查詢
SELECT * FROM table_name MATCH(ft_index) AGAINST('查詢字符串');
  1. 組合索引我認為是根據(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怎么查索引的都是無效的

索引的使用也是要講基本法的

什么場景不適合用索引?

  1. 數(shù)據(jù)過少的表,不需要用索引。因為數(shù)據(jù)較少,MYSQL會將數(shù)據(jù)讀到內(nèi)存里去,有點類似于緩存。這樣查詢速度會非???。不要使用索引
  2. 經(jīng)常增刪改的字段不要使用索引。因為本身建立索引和維護索引是有開銷的。如果經(jīng)常變化的字段加上索引會拖慢操作的效率
  3. 不常被作為條件的字段,不要使用索引。不作為條件的字段除了無法通過索引加速以外,還占用磁盤空間。帶來了維護壓力

什么場景適合使用索引?

  1. 首先當然是主鍵索引。每個表都應該有主鍵索引
  2. 經(jīng)常作為查詢條件在WHERE或者ORDER BY 語句中出現(xiàn)的列要建立索引
  3. 查詢中與其他表關(guān)聯(lián)的字段,外鍵關(guān)系建立索引
  4. 業(yè)務上要防止重復的字段,應該加上唯一索引
  5. 用于聚合函數(shù)的字段,比如 count(col) sum(col)。應該建立索引

最后,很多朋友會問,我加了索引,但是不知道sql到底有沒有用到索引。這個時候,只需要拿出索引大殺器explain 在你的sql前面就可以了

explain工具

概要描述

  • 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)注就更好了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 索引 數(shù)據(jù)庫中的查詢操作非常普遍,索引就是提升查找速度的一種手段 索引的類型 從數(shù)據(jù)結(jié)構(gòu)角度分 1.B+索引:傳統(tǒng)...
    一凡呀閱讀 3,197評論 0 8
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當在唯一索引所對應的列上鍵入重復值時,會觸發(fā)此異常。 O...
    我想起個好名字閱讀 5,916評論 0 9
  • 一、MySQL優(yōu)化 MySQL優(yōu)化從哪些方面入手: (1)存儲層(數(shù)據(jù)) 構(gòu)建良好的數(shù)據(jù)結(jié)構(gòu)??梢源蟠蟮奶嵘覀僑...
    寵辱不驚丶歲月靜好閱讀 2,633評論 1 8
  • MySQL性能調(diào)優(yōu) 索引 索引是什么 官方介紹索引是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)。筆者理解索引相當于一本書...
    陳小陌丿閱讀 1,530評論 0 4
  • 標題 列表 鏈接和圖片 引用 粗體和斜體 代碼引用 表格 小結(jié): 學習更多,可參考 Markdown 語法說明 (...
    Jay_Chen閱讀 284評論 0 0

友情鏈接更多精彩內(nèi)容