索引——談談你對索引的認識和理解


為什么要用索引?

一般的應用系統,讀寫比例在10:1左右,插入操作和一般的更新操作很少出現性能問題,在生產環境中,我們遇到最多的,也是最容易出問題的,還是一些復雜的查詢操作,因此對查詢語句的優化顯然是重中之重。說起加速查詢,就不得不提到索引了。

索引是什么?

索引在MySQL中也叫做“鍵”,是存儲引擎用於快速找到記錄的一種數據結構。

索引對於良好的性能非常關鍵,尤其是當表中的數據量越來越大時,索引對於性能的影響愈發重要。

索引優化應該是對查詢性能優化最有效的手段了。索引能夠輕易將查詢性能提高好幾個數量級。

索引相當於字典的音序表,如果要查某個字,如果不使用音序表,則需要從幾百頁中逐頁去查。

索引原理:

與我們查閱圖書所用的目錄是一個道理:先定位到章,然后定位到該章下的一個小節,然后找到頁數。相似的例子還有:查字典,查火車車次,飛機航班等.

本質都是:通過不斷地縮小想要獲取數據的范圍來篩選出最終想要的結果,同時把隨機的事件變成順序的事件,也就是說,有了這種索引機制,我們可以總是用同一種查找方式來鎖定數據。

索引兩大類型:

hash類型的索引:查詢單條快,范圍查詢慢

btree類型的索引:b+樹,層數越多,數據量指數級增長(我們就用它,因為innodb默認支持它)

 

索引的功能:加速查找,約束功能

適合建索引的字段:

  1. 經常被查詢的字段,即在where子句中出現的字段
  2. 在分組的字段,即在group by子句中出現的字段
  3. 存在依賴關系的子表和父表之間的聯合查詢,即主鍵或外鍵字段
  4. 設置唯一完整性約束的字段

不適合建索引字段:

  1. 在查詢中很少被使用的字段
  2. 擁有許多重復值的字段

創建索引:

創建索引:就是在表的一個字段或者多個字段上建立索引

普通索引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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM