為什麼要用索引? 一般的應用系統,讀寫比例在10:1左右,插入操作和一般的更新操作很少出現性能問題,在生產環境中,我們遇到最多的,也是最容易出問題的,還是一些複雜的查詢操作,因此對查詢語句的優化顯然是重中之重。說起加速查詢,就不得不提到索引了。 索引是什麼? 索引在MySQL中也叫做“鍵”,是存儲引 ...
為什麼要用索引?
一般的應用系統,讀寫比例在10:1左右,插入操作和一般的更新操作很少出現性能問題,在生產環境中,我們遇到最多的,也是最容易出問題的,還是一些複雜的查詢操作,因此對查詢語句的優化顯然是重中之重。說起加速查詢,就不得不提到索引了。
索引是什麼?
索引在MySQL中也叫做“鍵”,是存儲引擎用於快速找到記錄的一種數據結構。
索引對於良好的性能非常關鍵,尤其是當表中的數據量越來越大時,索引對於性能的影響愈發重要。
索引優化應該是對查詢性能優化最有效的手段了。索引能夠輕易將查詢性能提高好幾個數量級。
索引相當於字典的音序表,如果要查某個字,如果不使用音序表,則需要從幾百頁中逐頁去查。
索引原理:
與我們查閱圖書所用的目錄是一個道理:先定位到章,然後定位到該章下的一個小節,然後找到頁數。相似的例子還有:查字典,查火車車次,飛機航班等.
本質都是:通過不斷地縮小想要獲取數據的範圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,我們可以總是用同一種查找方式來鎖定數據。
索引兩大類型:
hash類型的索引:查詢單條快,範圍查詢慢
btree類型的索引:b+樹,層數越多,數據量指數級增長(我們就用它,因為innodb預設支持它)
索引的功能:加速查找,約束功能
適合建索引的欄位:
- 經常被查詢的欄位,即在where子句中出現的欄位
- 在分組的欄位,即在group by子句中出現的欄位
- 存在依賴關係的子表和父表之間的聯合查詢,即主鍵或外鍵欄位
- 設置唯一完整性約束的欄位
不適合建索引欄位:
- 在查詢中很少被使用的欄位
- 擁有許多重覆值的欄位
創建索引:
創建索引:就是在表的一個欄位或者多個欄位上建立索引
普通索引index:加速查找
唯一索引:
- 主鍵索引(primary key):加速查找+約束(不為空、不能重覆)
- 唯一索引(unique):加速查找+約束(不能重覆)
聯合索引:
- primary key(id,name):聯合主鍵索引
- unique(id,name):聯合唯一索引
- index(id,name):聯合普通索引
創建普通索引:
普通索引:創建索引時,不附加任何限制條件(唯一、非空等限制),該索引可以創建在任何列上。
語法:create table 表名( ... ,index|key [索引名](列名, [(長度)] [asc|desc]) ); //長度和asc|desc可省略
案例:create table uid( id int, ..., index index_id(id) );
create table uid( id int,
...,
index index_id(id)
);
通過explain查看索引是否被執行:
explain select * from uid where id=001;
在已經存在的欄位上建立索引:
語法:create index 索引名 on 表名 (列名 [(長度)] [asc|desc])
案例:
create index index_id on uid(id);
通過alter來創建索引:
語法:altert able 表名 add index|key 索引名 (列名 [(長度)] [asc|desc])
案例:
alter table uid add index index_id(id);
創建唯一索引:
唯一索引:就是限制某個或者多個欄位的值必須唯一,通過該類型的索引可以快速的查詢某條記錄
語法:create table 表名( ... , unique index|key [索引名](列名 [(長度)] [asc|desc]) );
案例:
create table uid(id int, ..., unique index index_id(id) );
已有的表上建索引:
案例
create unique index index_id on uid(id);
通過alter添加索引:
案例
alter table uid add unique index index_id(id);
創建全文索引
全文索引主要關聯在數據類型為char、varchar和text的欄位上,以便能夠快速的查詢數據量較大的字元串類型的欄位
語法:create table 表名( ... , fulltext index|key [索引名](列名 [(長度)] [asc|desc]) );
創建多列索引(聯合索引)
多列索引:是指創建索引的欄位不是一個欄位,而是多個欄位,雖然可以通過關聯的欄位進行查詢,但是只有查詢條件中使用了所關聯的欄位中的第一個欄位,多列索引才會被使用。
語法:create table 表名( ... , index|key [索引名](列名1 [(長度)] [asc|desc]) ,列名2 [(長度)] [asc|desc]) );
案例
create table uid( ...,
name varchar(20),
loc varchar(40),
index index_name_loc(name, loc)
);
已經存在的表上創建索引:
案例
create index index_name_loc on uid(name, loc);
alter table uid add index index_name_loc(name,loc);
多個單列索引在多條件查詢時只會生效第一個索引!所以多條件聯合查詢時最好建聯合索引!
最左首碼原則:
顧名思義是最左優先,以最左邊的為起點任何連續的索引都能匹配上,
註:如果第一個欄位是範圍查詢需要單獨建一個索引
註:在創建聯合索引時,要根據業務需求,where子句中使用最頻繁的一列放在最左邊。這樣的話擴展性較好,比如 userid 經常需要作為查詢條件,而 mobile 不常常用,則需要把 userid 放在聯合索引的第一位置,即最左邊
聯合索引本質:
當創建(a,b,c)聯合索引時,相當於創建了(a)單列索引,(a,b)聯合索引以及(a,b,c)聯合索引
想要索引生效的話,只能使用 a,和a,b,和a,b,c三種組合;當然,我們上面測試過,a,c組合也可以,但實際上只用到了a的索引,c並沒有用到!
聯合索引總結:
需要加索引的欄位,要在where條件中;
數據量少的欄位不需要加索引(因為建索引有開銷,速度反而慢);
如果where條件中是or關係,加索引不起作用;
聯合索引比每個列分別建索引更有優勢,因為建索引有開銷,順序也要註意,一般不超過7,8個,應該將嚴格的索引放在前面,這樣篩選力度會更大,效率更高。
刪除索引:
語法:drop index index_name on table_name;
案例
drop index index_id on uid;
參考文獻:
https://www.cnblogs.com/bypp/p/7755307.html
https://blog.csdn.net/fengxiaolu311/article/details/82716294