mysql索引

索引使用建議:前端

a,常常檢索的列mysql

b,常常用於錶鏈接的列sql

c,常常排序/分組的列session

索引不使用建議:數據結構

a,基數很低的列函數

b,常常用於錶鏈接的列優化

c,常常排序/分組的列spa

 

innodb主鍵特色:設計

a,索引定義時,若不顯示包含主鍵,會隱式加入主鍵值;server

b,索引定義時,若顯示包含主鍵,會加入主鍵值;

c,在5.6.9後,優化器已經能自動識別索引末尾的主鍵值(index extensions),在這以前則須要顯式加上主鍵列才能夠被識別;

d,修改主鍵必然從新拷貝整張表

 

主鍵的選擇建議:

a,對業務透明無心義,免收業務變化的影響;

b,主鍵要不多修改和刪除;(刪除還好,影響不大,innodb小範圍作數據頁合併)

c,主鍵最好是自增的;

d,不要具備動態屬性,例如最後修改時間戳;(若是常常變化會致使彙集索引的值發生變化,相應的致使btree索引值旋轉、分裂、位移)

 

innodb彙集索引選擇順序原則:

a,顯示聲明的主鍵;

b,第一個不包含null值的惟一索引列;

c,內置的rowid(自增邏輯值,6byte且不可引用)

 innodb彙集索引不建議選用頻繁更新、隨機寫入(離散IO)

 

惟一索引(unique key)

a,不容許具備索引值相同的行,從而禁止重複的索引或鍵值;

b,在惟一約束上,和主鍵同樣(以myisam引擎爲表明);

c,和主鍵區別:1,惟一索引容許有空值(null) 2,一個表只能有一個主鍵,但能夠有多個惟一索引 3,innodb表中主鍵必須是彙集索引,但彙集索引可能不是主鍵(未定義主鍵、也沒有非null的惟一索引時會選擇rowid) 4,惟一索引約束能夠臨時禁用,但主鍵不行(set session  UNIQUE_CHECKS = 0;),即使禁用惟一性約束,也沒法插入相同值。那麼,關閉還有什麼意義?大量導入數據時就不須要每行都檢測惟一性是否衝突,最後一次性檢測有沒有重複,效率更高些。若是不想告警可使用 on duplicate key update(先insert,若是失敗就update);

 

聯合索引(combined indexes,multiple-column indexes)

a,多列組成,因此也叫多列索引

b,適合where條件中的多列組合

c,有時候,還能夠用於避免回表(覆蓋索引)

d,以往有列引用順序,如今已經沒有這個限制了

e,mysql還不支持多列不一樣排序規則(order by a.b.c,desc;這個不ok)

f,聯合索引建議:1,where條件中,常常同時出現的列放在聯合索引中。2,聯合索引包含的列數越多,會增長死鎖的機率。

 

覆蓋索引:

a,經過索引數據結構,便可直接返回數據,不須要回表

b,執行計劃中,顯示關鍵字using index

 

前綴索引(prefix indexes):

部分索引的緣由:1,char/varchar太長所有作索引的話,效率太差,存在浪費。2,blob/text類型不能整列做爲索引列,所以須要前綴索引。

部分索引的選擇建議:1,統計平均值。2,遵循2/8原則(覆蓋80%數據就OK)

 

外鍵約束(foreign key constraints)

a,確保存儲在外鍵表中的數據一致性,完整性;

b,外鍵前提:本表列須與外鍵類型相同(外鍵須是外表主鍵);

c,外鍵選擇原則:1,爲關聯字段建立外鍵。2,全部的鍵都必須惟一。3,避免使用複合鍵;4,外鍵老是關聯惟一的鍵字段。

mysql支持全文索引,但不建議使用IO,內存,CPU都是瓶頸。

 可使用pt-duplicate-key-checker檢查冗餘索引,pt-index-usage檢查低利用率索引,並提供刪除建議。

 

索引如何提升sql效率?

a,提升數據檢索效率

b,提升聚合函數效率,sum()、avg()、count()

c,有時能夠避免回表

d,減小多表關聯掃描行數

e,惟1、外鍵索引還能夠做爲輔助約束

f,列定義DEFAULT NULL時,NULL值也會有索引,存放在索引樹的最左端,最前端部分,所以儘可能不要定義爲NULL。

 

何時索引不可用?

a,經過索引掃描的記錄數超過30%,會變成全表掃描

b,聯合索引中,第一個索引列使用範圍查詢(這時用到部分索引)

c,聯合索引中,第一個查詢條件不是最左索引列

d,模糊查詢條件列最左通配符%開始

e,HEAP表使用HASH索引時,使用範圍檢索或者ORDER BY

f,多表關聯時,排序字段不屬於驅動表,沒法利用索引完成排序(這點很重要,詳見下圖案例,強制更改驅動表可能影響結果集)

g,兩個獨立索引,其中一個用於檢索,一個用於排序(只能用到一個)

 

 

ICP(index condition pushdown)是mysql5.6的新特性,其機制會讓索引的其餘部分也參與過濾,減小引擎層和server層數據傳輸和回表請求,一般狀況下可大幅度提高查詢效率。

 

覆蓋索引:

假設有這樣的索引:key 'idx1'('id','user','passwd')

覆蓋索引都被用到:

a,select id,user,passwd from t1 where id=?

b,select id,user,passwd from t1 where id=? and user=?

c,select id,user,passwd from t1 where id=? and user=? and passwd=?

覆蓋索引部分被用到:

a,select id,user,passwd from t1 where passwd=? and id=?

b,select id,user from t1 where id =? order by user;

c,select id,user from t1 where id=? order by passwd;

 

explain之key_len

a,正常狀況等於索引列字節長度

b,字符串類型須要同時考慮字符集因素

c,若容許null,再+1

d,變長類型(如varchar)再+2

 key_len只計算利用索引完成數據過濾的索引長度

不包括用於group by\order by的索引長度

即:若是order by也使用了索引,不會將其計算在key_len以內

例如:聯合索引(c1,c2,c3),where c1 = ? and c2 = ? order by c3.這時,key_len只會顯示c1+c2的長度

#eq_range_index_dive_limit  默認值是200,in值只要不超過200都是等值查詢,超過200執行代價會有變化。

 

a in (1, 5) 等價於
a = 1
union
a = 5

 

索引設計建議:

a,一個索引裏包含的個數最好不要超過5個

b,一個表的索引數,不要太多,通常不要超過5個

c,聯合索引中把過濾性高(基數大)的列放在前面

相關文章
相關標籤/搜索