背景:總結mysql索引相關的知識點.
MySQL 索引及查詢優化總結
ps:其中的b+樹有誤。對or的使用有誤。總體還是很詳盡的
注意:索引是在存儲引擎中實現的,也就是說不同的存儲引擎,會使用不同的索引。MyISAM和InnoDB存儲引擎:只支持BTREE索引,也就是說默認使用BTREE,不能夠更換。MEMORY/HEAP存儲引擎:支持HASH和BTREE索引。
1、索引我們分為四類來講單列索引(普通索引,唯一索引,主鍵索引)、組合索引、全文索引、空間索引、
mysql索引類型:
- 主鍵索引 primary key 不允許null
- 唯一索引 union key 可以為null
- 普通索引 index
- 聯合索引
- 全文索引
建立索引的原則:
- 最左匹配原則 遇到范圍查詢(>、<、between、like)就停止匹配。 則mysql實際建的索引為:(a) (a,b) (a,b,c) (a,b,c,d)
- 盡量選擇區分度高的列作為索引
- =和in可以亂序
- 索引列不能參與計算,保持列“干凈”。 假如索引列參與計算的話,那每次檢索時,都會先將索引計算一次,再做比較,顯然成本太大。
- 盡量的擴展索引,不要新建索引
補充:盡量擴展索引、不要新建索引 mysql目前主要索引有:FULLTEXT,HASH,BTREE 好的索引可以提高我們的查詢效率,不好的索引不但不會起作用,反而給DB帶來負擔,基於BTREE結構,插入、修改都會重新調整索引結構,存儲成本增加,寫效率降低,同時DB系統也要消耗資源去維護。 基於剛才的最左匹配原則,盡量在原有基礎上擴展索引,不要新增索引。 能用單索引,不用聯合索引;能用窄索引,不用寬索引;能復用索引,不新建索引。 回到線上案例: nc_tms_order、ct_order看看分別有哪些索引
索引的不足:空間,時間,開銷
常用優化總結:
-
有索引但未被用到的情況(不建議) (1) Like的參數以通配符%開頭時 (2) where條件不符合最左前綴原則時 (3) 使用!= 或 <> 操作符時(使用>或<會比較高效。)(4) 索引列參與計算 (5) 對字段進行null值判斷 (6) 使用or來連接條件(兩端都有索引才行)
-
避免select * 在解析的過程中,會將'*' 依次轉換成所有的列名,這個工作是通過查詢數據字典完成的,這意味着將耗費更多的時間。
-
order by 語句優化 1)重寫order by語句以使用索引;2)為所使用的列建立另外一個索引 3)避免在order by子句中使用表達式
- 提高GROUP BY 語句的效率, 可以通過將不需要的記錄在GROUP BY 之前過濾掉
-
使用 varchar/nvarchar 代替 char/nchar
-
在Join表的時候使用相當類型的例,並將其索引
- 優化嵌套查詢:子查詢可以被更有效率的連接(Join)替代;
- 很多時候用 exists 代替 in 是一個好的選擇
mysql索引的分類
MySQL索引背后的數據結構及算法原理(講的很透徹)
MySQL索引的分類(根據數據結構)(明白具體的分類)
理解mysql搜索引的實現:
MyISAM索引實現:
MyISAM中索引檢索的算法為首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然后以data域的值為地址,讀取相應數據記錄。
MyISAM的索引方式也叫做“非聚集”的,之所以這么稱呼是為了與InnoDB的聚集索引區分。
在MyISAM中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重復。
InnoDB索引實現:
MyISAM索引和InnoDB索引的不同:
第一個重大區別是InnoDB的數據文件本身就是索引文件。innodb 聚集索引data域存放的是數據的記錄,mylsam的data域存儲的是記錄的地址
從上文知道,MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。而在InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。
這種索引叫做聚集索引。因為InnoDB的數據文件本身要按主鍵聚集,所以InnoDB要求表必須有主鍵(MyISAM可以沒有),如果沒有顯式指定,則MySQL系統會自動選擇一個可以唯一標識數據記錄的列作為主鍵,如果不存在這種列,則MySQL自動為InnoDB表生成一個隱含字段作為主鍵,這個字段長度為6個字節,類型為長整形。
第二個與MyISAM索引的不同是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作為data域。mylsam輔助索引data域存儲的是地址。
exists和in的區別?