Mysql深入四:索引優化與執行計劃(十條規則 索引策略)

目錄

一、索引分類

二、Mysql創建索引基本命令

三、執行計劃

四、索引策略優化


一、索引分類

1、聚集索引

數據行的物理順序與列值(一般是主鍵的那一列)的邏輯順序相同,一個表中只能擁有一個聚集索引,數據和索引是在同一個葉子節點上的,存儲放在一起

主鍵索引:一種特殊的唯一索引,主鍵索引不允許爲空,值必須唯一;主鍵索引就是B+樹;一般建立表的同時創建主鍵索引

2、非聚集索引

該索引中索引的邏輯順序與磁盤上行的物理存儲順序不同,一個表中可以擁有多個非聚集索引)數據和索引是在不同一個葉子節點上的,不是存儲放在一起。通過一個索引,去主鍵索引找

  • 普通索引:即一個索引只包含單個列,一個表可以有多個單列索引
  • 唯一索引:索引列的值必須唯一,但允許有空值(主鍵索引不允許爲空)
  • 複合索引:即一個索引包含多個列index(a,b,c)

 

二、Mysql創建索引基本命令

查看索引 show index from table
創建索引 create [unique] index index_name on mytable(columnname)
刪除索引 drop index indexName on mytable

演示

創建複合索引:CREATE INDEX age_name_sex_index ON id(age,name,sex)

查看索引:SHOW INDEX FROM id

刪除索引:DROP INDEX age_name_sex_index ON id

 

三、執行計劃

使用EXPLAIN關鍵字可以模擬優化器執行SQL查詢語句,從而知道MySQL是如何處理你的SQL語句的。分析你的查詢語句或是表結構的性能瓶頸

語法:explain sql語句

執行計劃的作用

表的讀取順序、數據讀取操作的操作類型、哪些索引可以使用、哪些索引被實際使用、表之間的引用、每張表有多少行被優化器查詢

執行計劃包含信息

id select_type table type possible_keys key key_len ref rows extra

重要研究:type、key、key_len、extra

type 訪問類型,表示找到所查詢數據的方法
key 當此值存在時,說明索引生效了,但是充分利用就不知曉(是否利用了索引)
key_len 來計算索引是否被充分利用(是否充分用了索引)
extra

1、Using where說明,SQL使用了where條件過濾數據

2、Using index說明,SQL所需要返回的所有列數據均在一棵索引樹上,而無需訪問實際的行記錄

對type解釋的比較好的博客:https://www.jianshu.com/p/b5c01bd4a306

對extra解釋的比較好的博客:https://www.cnblogs.com/linjiqin/p/11254247.html

 

執行計劃之key_len字段計算分析

計算:類型(int+0,char+0,varchar+2)、長度、字符編碼、是否允許爲空(空+1 不空+0)有關 

key_len=字符長度*字節數+類型+是否允許爲空

其中:char和varchar的長度是指字符數,一個字符在編碼gbk爲2個字節、utf-8爲3個字節,需要字符數*字節

例如:

name varchar(50) 表示是varchar類型,長度爲50,允許爲空,假設是utf8編碼 key_len=50*3+2+1=153
age int(255) 表示int類型,字節數爲4,允許爲空,跟長度和編碼無關 key_len=4+1=5

對於Mysql的整數類型說明補充:這裏顯示的寬度和數據類型的取值範圍是沒有任何關係的,顯示寬度只是指明Mysql最大可能顯示的數字個數,數值的位數小於指定的寬度時會由空格填充;如果插入了大於顯示寬度的值,只要該值不超過該類型的取值範圍,數值依然可以插入,而且能夠顯示出來。

演示:

EXPLAIN
SELECT age,name,sex FROM id WHERE age=2 AND name='lisi' AND sex='1'

分析

  • key值存在,說明使用了索引
  • key_len=40(age=4,name=10*3+2=32,sex=1*3+1(sex是可以爲Null+1))
  • 複合索引每個列都需要計算,全部列都生效了纔是充分利用,上面例子三個列都生效,所以是充分利用了索引

 

key_len總結

  1. 變長字段需要額外的2個字節(VARCHAR值保存時只保存需要的字符數,另加一個字節來記錄長度(如果列聲明的長度超過255,則使用兩個字節),所以VARCAHR索引長度計算時候要加2),固定長度字段不需要額外的字節。
  2. NULL都需要1個字節的額外空間,所以索引字段最好不要爲NULL,因爲NULL讓統計更加複雜並且需要額外的存儲空間。
  3. 複合索引有最左前綴的特性,如果複合索引能全部使用上,則是複合索引字段的索引長度之和,這也可以用來判定複合索引是否部分使用,還是全部使用。
  4. 一張表中不能全是索引,底層維護索引效率太低了。並且之後的查詢都是從索引拿,就是都使用覆蓋索引了

 

四、索引策略優化

索引一般都是根據sql語句來作的index(a,b,c),但是作成之後,索引的順序就是對sql造成影響

sql沒有索引時, where掃描是從右到左的

有索引,按照索引定義的方式來執行 比如有index(a,b,c),執行順序就是a,b,c,這個跟後面where的順序無關,但是where中有a才能執行,有bc沒a還是不能執行

十大索引策略:

1、儘量全值匹配 就是準確不用like
2、最佳左前綴法則 如果是複合索引,要遵循最左前綴法則,指的是查詢從索引的最左前列開始並且不跳過索引中的列
3、不在索引列上做任何操作(計算、函數、(自動or手動)類型轉換),會導致索引失效而轉向全表掃描
4、範圍條件放最後 意思是sql有範圍查詢,定義複合索引應該把它放最後(存儲引擎不能使用索引中範圍條件右邊的列)
5、儘量使用覆蓋索引 只訪問索引的查詢(索引列和查詢列一致),減少select *  查出來的都是索引,叫做覆蓋索引
6、mysql 在使用不等於(!= 或者<>)的時候無法使用索引會導致全表掃描
7、注意null/not null對索引的可能影響
8、Like查詢要當心,%不要放第一
9、字符類型加引號
10、OR改UNION效率高

CREATE INDEX age_name_sex_index ON id(age,name,sex)

2、最佳左前綴法則

如果是複合索引,要遵循最左前綴法則,指的是查詢從索引的最左前列開始並且不跳過索引中的列

索引全有效

索引全失效(首個age索引不在,失效)

age索引有效(跳過了name,導致c索引失效)

4、範圍條件放最後(索引定義時是age在第一,使用範圍,導致其後的索引都失效)

設置索引應該根據SQL來定義索引,索引應該設置成CREATE INDEX age_name_sex_index ON id(name,sex,age)

5、儘量使用覆蓋索引

針對下列情況,可以使用全索引覆蓋

使用全索引覆蓋,SELECT age,name,sex FROM id WHERE age<2 AND name='lisi' AND sex='1'(age、name、sex都是索引列)

7、Like查詢要當心

like 後第一個加%時,影響索引及後續索引

所以Like的%不要加在第一個

 

索引優化口訣:

全值匹配我最愛,最左前綴要遵守;

帶頭大哥不能死,中間兄弟不能斷;

索引列上少計算,範圍之後全失效;

LIKE百分寫最右,覆蓋索引不寫*;

不等空值還有OR,索引影響要注意;

VARCHAR引號不可丟, SQL優化有訣竅
 

題目:
index(a,b,c)

Where語句 索引是否被使用
where a = 3 a被使用
where a = 3 and b = 5 ab被使用
where a = 3 and b = 5 and c = 4 abc被使用
where b = 3 或者 where b = 3 and c = 4  或者 where c = 4  沒有被使用
where a = 3 and c = 5  a被使用
where a = 3 and b > 4 and c = 5 ab被使用
where a = 3 and b like 'kk%' and c = 4 abc被使用
where a = 3 and b like '%kk' and c = 4 a被使用
where a = 3 and b like '%kk%' and c = 4   a被使用
where a = 3 and b like 'k%kk%' and c = 4 abc被使用


 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章