數據庫複習之索引和explain

索引

查看錶中已經存在 index:show index from table_name;

創建和刪除索引
索引的創建可以在CREATE TABLE語句中進行,也可以單獨用CREATE INDEX或ALTER TABLE來給表增加索引。刪除索引可以利用ALTER TABLE或DROP INDEX語句來實現。

(1)使用ALTER TABLE語句創建索引。
語法如下:

alter table table_name add  index index_name (column_list) ;
alter table table_name add unique (column_list) ;
alter table table_name add  primary key (column_list) ;

其中包括普通索引、UNIQUE索引和PRIMARY KEY索引3種創建索引的格式,table_name是要增加索引的表名,column_list指出對哪些列進行索引,多列時各列之間用逗號分隔。索引名index_name可選,缺省時,MySQL將根據第一個索引列賦一個名稱。另外,ALTER TABLE允許在單個語句中更改多個表,因此可以同時創建多個索引。
創建索引的示例如下:

mysql> use tpsc
Database changed
mysql> alter table tpsc add index shili (tpmc ) ;
Query OK, 2 rows affected (0.08 sec)
Records: 2 Duplicates: 0 Warnings: 0

創建組合索引

ALTER TABLE em_ca ADD INDEX INDEX_CA_CONTACT (`CA_CONTACT`,‘CA_NAME’);

(2)使用CREATE INDEX語句對錶增加索引。
能夠增加普通索引和UNIQUE索引兩種。其格式如下:

create index index_name on table_name (column_list) ;
create unique index index_name on table_name (column_list) ;

說明:table_name、index_name和column_list具有與ALTER TABLE語句中相同的含義,索引名不可選。另外,不能用CREATE INDEX語句創建PRIMARY KEY索引。

(3)刪除索引。
刪除索引可以使用ALTER TABLE或DROP INDEX語句來實現。DROP INDEX可以在ALTER TABLE內部作爲一條語句處理,其格式如下:

drop index index_name on table_name ;
alter table table_name drop index index_name ;
alter table table_name drop primary key ;

其中,在前面的兩條語句中,都刪除了table_name中的索引index_name。而在最後一條語句中,只在刪除PRIMARY KEY索引中使用,因爲一個表只可能有一個PRIMARY KEY索引,因此不需要指定索引名。如果沒有創建PRIMARY KEY索引,但表具有一個或多個UNIQUE索引,則MySQL將刪除第一個UNIQUE索引。
如果從表中刪除某列,則索引會受影響。對於多列組合的索引,如果刪除其中的某列,則該列也會從索引中刪除。如果刪除組成索引的所有列,則整個索引將被刪除。
刪除索引的操作,如下面的代碼:

mysql> drop index shili on tpsc ;
Query OK, 2 rows affected (0.08 sec)
Records: 2 Duplicates: 0 Warnings: 0

該語句刪除了前面創建的名稱爲“shili”的索引。

explain 執行計劃

explain 指的是某個sql語句的執行計劃:explain sql語句

id: 1
select_type: SIMPLE(簡單查詢,不是多表查詢和複雜查詢) 可能的值:simple,primary,union,dependent union,union result
table: php114(表名)
type: ALL()     可能的值:system,const(最優化,使用了主鍵或者唯一健),eq_ref,ref.ref_or_null,index_merge
possible_keys: NULL         提示使用哪個索引會在該表中找到行
key: NULL()     mysql使用的索引,簡單且重要
key_len: NULL()     mysql使用的索引長度
ref: NULL          顯示使用哪個列或者常數與key一起從表中選擇行
rows: 6          mysql執行查詢的行數,簡單且重要,數值越大越不好,說明沒有用好索引
Extra:          包含mysql解決查詢的詳細信息

在這裏插入圖片描述

組合索引的最左優先原則

最左前綴匹配原則

在mysql建立聯合索引時會遵循最左前綴匹配的原則,即最左優先,在檢索數據時從聯合索引的最左邊開始匹配,組合索引的第一個字段必須出現在查詢組句中,這個索引纔會被用到,示例:
對列col1、列col2和列col3建一個聯合索引:

KEY test_col1_col2_col3 on test(col1,col2,col3);

聯合索引 test_col1_col2_col3 實際建立了(col1)、(col1,col2)、(col,col2,col3)三個索引。

上面這個查詢語句執行時會依照最左前綴匹配原則,檢索時會使用索引(col1,col2)進行數據匹配。

注意

索引的字段可以是任意順序的,如:

SELECT * FROM test WHERE col1=“1” AND clo2=“2”
SELECT * FROM test WHERE col2=“2” AND clo1=“1”
這兩個查詢語句都會用到索引(col1,col2),mysql創建聯合索引的規則是首先會對聯合合索引的最左邊的,也就是第一個字段col1的數據進行排序,在第一個字段的排序基礎上,然後再對後面第二個字段col2進行排序。其實就相當於實現了類似 order by col1 col2這樣一種排序規則。

所以題目會創建三個索引(plat_order_id)、(plat_order_id與plat_game_id的組合索引)、(plat_order_id、plat_game_id與plat_id的組合索引)。根據最左匹配原則,where語句必須要有plat_order_id才能調用索引(如果沒有plat_order_id字段那麼一個索引也調用不到),如果同時出現plat_order_id與plat_game_id則會調用兩者的組合索引,如果同時出現三者則調用三者的組合索引。

思考

對於聯合索引(col1,col2,col3),查詢語句SELECT * FROM test WHERE col2=2;是否能夠觸發索引?

EXPLAIN SELECT * FROM test WHERE col2=2;
EXPLAIN SELECT * FROM test WHERE col1=1;
藉助mysql查詢優化器explain,explain會糾正sql語句該以什麼樣的順序執行效率最高,最後才生成真正的執行計劃,觀察explain中上述兩個sql語句結果的type字段。查詢中分別是:

type: index
type: ref
index:這種類型表示mysql會對整個該索引進行掃描。要想用到這種類型的索引,對這個索引並無特別要求,只要是索引,或者某個聯合索引的一部分,mysql都可能會採用index類型的方式掃描。但是呢,缺點是效率不高,mysql會從索引中的第一個數據一個個的查找到最後一個數據,直到找到符合判斷條件的某個索引。所以,上述語句會觸發索引。
ref:這種類型表示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,效率提升可想而知!

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