全域性索引 字首索引 面試系列 索引種類與優化

2021-10-16 01:40:58 字數 3236 閱讀 7618

索引雖然快,但是占用了額外的空間,所以需要有一定權衡

回表查詢

innodb的普通索引無法直接定位行記錄,所以普通索引的查詢過程是怎麼樣的呢?

通常情況下,需要掃碼兩遍索引樹。這就是所謂的回表查詢,先定位主鍵值,再定位行記錄,它的效能較掃一遍索引樹更低。

覆蓋索引

只需要在一棵索引樹上就能獲取sql所需的所有列資料,無需回表,速度更快。常見的方法是:將被查詢的字段,建立到聯合索引裡去。

最左欄位全域性有序,其餘字段區域性有序(僅在它前面字段相同的情況下有序)

實現覆蓋索引

使用者表:id主鍵索引,name普通索引(非唯一),***無索引;

四行記錄:其中name普通索引存在重覆記錄lisi;

select id,name from user where name='shenjian';
普通索引葉子節點儲存了主鍵id和name,通過name的索引樹即可獲取id和name,無需回表,符合索引覆蓋,效率較高

select id,name,**** from user where name='shenjian';*
索引葉子節點儲存了主鍵id和name,但是***字段必須回表查詢才能夠獲取。

可以把(name)單列索引公升級為聯合索引(name, ***),這樣葉子節點就存(name,***,id)了。

mysql推薦使用聯合索引而不是單值索引,為什麼要使用聯合索引?

減少開銷。建乙個聯合索引(col1,col2,col3),實際相當於建了(col1),(col1,col2),(col1,col2,col3)三個索引。每多乙個索引,都會增加寫操作的開銷和磁碟空間的開銷。對於大量資料的表,使用聯合索引會大大的減少開銷!

覆蓋索引。對聯合索引(col1,col2,col3),如果有如下的sql: select col1,col2,col3 from test where col1=1 and col2=2。那麼mysql可以直接通過遍歷索引取得資料,而無需回表,這減少了很多的隨機io操作。**減少io操作,特別的隨機io其實是dba主要的優化策略。所以,在真正的實際應用中,覆蓋索引是主要的提公升效能的優化手段之一。

效率高。索引列越多,通過索引篩選出的資料越少。有1000w條資料的表,有如下sql:select from table where col1=1 and col2=2 and col3=3,假設假設每個條件可以篩選出10%的資料,如果只有單值索引,那麼通過該索引能篩選出1000w10%=100w條資料,然後再回表從100w條資料中找到符合col2=2 and col3= 3的資料,然後再排序,再分頁;如果是聯合索引,通過索引篩選出1000w10% 10% *10%=1w,效率提公升可想而知

最左字首原則是指mysql建立聯合索引的b+樹是按照從左到右的字段基礎上進行排序插入

//注意聯合索引是建乙個索引,而不是三個索引

key `a_b_c_index` (`username`,`password`,`usertype`)

//使用索引 type=index

explain select * from user2 where password = '1';

//使用索引 type=ref

explain select * from user2 where username = '1' and password = '1';

//使用索引 type=ref 任意順序mysql的查詢優化器會幫你優化成索引可以識別的形式

explain select * from user2 where password = '1' and username = '1';

//使用索引 type=ref

explain select * from user2 where username= '1' and usertype= '1';

select * from *** where a>1 and b=2
普通索引建聯合索引(a,b),包含所有查詢字段資訊,但是仍然會進行回表查詢.

既然,索引樹已包含全部欄位的資訊,那為何不直接通過索引樹的字段來完成查詢,避免發生回表呢?原因是,聯合索引原理中只能保證區域性有序,一旦有非等值查詢後,後續字段無法直接通過索引樹確定範圍。

mysql 5.6 引入的索引下推優化(index condition pushdown), 可以在索引遍歷過程中,對索引中包含的字段先做判斷,直接過濾掉不滿足條件的記錄,減少回表次數。

主要在於change buffer的使用與否。

當需要更新乙個資料頁時,如果資料頁在記憶體中就直接更新,而如果這個資料頁還沒有在記憶體中的話,在不影響資料一致性的前提下,inoodb會將這些更新操作快取在change buffer中,這樣就不需要從磁碟中讀入這個資料頁了。

將change buffer中的操作應用到原資料頁,得到最新結果的過程稱為merge。

唯一索引不能使用change buffer,因為對於唯一索引來說,所有的更新操作都要先判斷這個操作是否違反唯一性約束。只有普通索引可以使用。

所以兩類索引在查詢能力上是沒差別的,主要考慮的是對更新效能的影響。在寫多讀少的情況下推薦使用普通索引

字首索引

對文字的前幾個字元(具體是幾個字元在建立索引時指定)建立索引,這樣建立起來的索引更小,所以查詢更快。

很長的字段,想做索引我們怎麼去優化他呢?

hash,把字段hash為另外乙個欄位存起來,每次校驗hash就好了,hash的索引也不大。

或者可以採用倒序,或者刪減字串這樣的情況去建立我們自己的區分度

比如本來是www.aobing@qq,com 其實前面的www.基本上是沒任何區分度的,所有人的郵箱都是這麼開頭的,你一搜一大堆出來,放在索引還浪費記憶體,你可以substring()函式擷取掉前面的,然後建立索引。我們所有人的身份證都是區域開頭的,同區域的人很多,那怎麼做良好的區分呢?reverse()函式翻轉一下,區分度可能就高了。

同樣地,order by 或 group by無法使用字首索引了。

全域性索引 字首索引 MySQL索引型別

等你點關注都等的長毛了 索引型別 mysql中我們常用的索引型別有五種 普通索引 唯一索引 主鍵索引 組合索引 全文索引 建立表 create table index test id int 11 default null,name varchar 11 default null,idno varc...

mysql索引種類(索引種類和建立索引)

一 mysql索引種類 1 加速查詢 查詢普通欄位和查詢有索引字段,哪個方式查詢速度快 根據索引來查字段速度更快 2 建立索引 為userinfo表email欄位建立索引 create index ix name on userinfo 建立欄位email索引檔案,起別名ix name為某個字段建立...

mysql索引種類 索引結構 索引優化

索引的資料結構和儲存 myisam和innodb都使用的是b tree資料結構。myisam的索引檔案僅僅儲存資料記錄的位址,和資料檔案分開存放。innodb是索引和資料儲存在一起。檢視乙個表的索引 show index from employee.titles 通常所說的索引型別 1.index ...