索引
索引是一種能夠加快數據的查詢的數據結構。mysql主要有兩種索引,HASH索引和B+Tree索引。
B+Tree索引:
Hash索引:
B+樹索引和哈希索引的區別
- 如果是等值查詢,那麼哈希索引明顯有絕對優勢,因爲只需要經過一次算法即可找到相應的鍵值;當然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然後再根據鏈表往後掃描,直到找到相應的數據;
- 從示意圖中也能看到,如果是範圍查詢檢索,這時候哈希索引就毫無用武之地了,因爲原先是有序的鍵值,經過哈希算法後,有可能變成不連續的了,就沒辦法再利用索引完成範圍查詢檢索;
- 同理,哈希索引也沒辦法利用索引完成排序,以及like ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實本質上也是範圍查詢);
- 哈希索引也不支持多列聯合索引的最左匹配規則;
- B+樹索引的關鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重複鍵值情況下,哈希索引的效率也是極低的,因爲存在所謂的哈希碰撞問題。
聚簇索引
索引B+Tree的葉子節點存儲了
整行數據
的是主鍵索引,也被稱之爲聚簇索引。
索引B+Tree的葉子節點存儲了主鍵的值
的是非主鍵索引,也被稱之爲非聚簇索引。
主鍵索引樹的葉子節點直接就是我們要查詢的整行數據, 而非主鍵索引的葉子節點是主鍵的值,查到主鍵的值以後,還需要再通過主鍵的值再進行一次查詢對應主鍵ID的數據(俗稱回表)。
覆蓋索引
指一個查詢語句的執行只用從索引中就能夠取得,不必從數據表中讀取。也可以稱之爲實現了索引覆蓋。 當一條查詢語句符合覆蓋索引條件時,MySQL只需要通過索引就可以返回查詢所需要的數據,這樣避免了查到索引後再回表操作,減少I/O提高效率。
聯合索引
多列b+tree,使用多列值組合而成的b+tree索引
遵循最左側原則,從左到右的使用索引中的字段,一個查詢可以只使用索引中的一部份,但只能是最左側部分。一般根據業務需求,where子句中使用最頻繁的一列放在最左邊。
索引下推
MySQL 5.6引入了索引下推優化,默認開啓,使用SET optimizer_switch = ‘index_condition_pushdown=off’;可以將其關閉。
官方文檔中給的例子和解釋如下: people表中(zipcode,lastname,firstname)構成一個索引
SELECT * FROM people WHERE zipcode='95054' AND lastname LIKE '%etrunia%' AND address LIKE '%Main Street%';
如果沒有使用索引下推技術,則MySQL會通過zipcode='95054’從存儲引擎中查詢對應的數據,返回到MySQL服務端,然後MySQL服務端基於lastname LIKE '%etrunia%'和address LIKE '%Main Street%'來判斷數據是否符合條件。 如果使用了索引下推技術,則MYSQL首先會返回符合zipcode='95054’的索引,然後根據lastname LIKE '%etrunia%'和address LIKE '%Main Street%'來判斷索引是否符合條件。如果符合條件,則根據該索引來定位對應的數據,如果不符合,則直接reject掉。
有了索引下推優化,可以在有like條件查詢的情況下,減少回表次數。
索引合併
對多個索引分別進行條件掃描,然後將它們各自的結果進行合併(intersect/union),最後回表。
查詢優化器
一條SQL語句的查詢,可以有不同的執行方案,至於最終選擇哪種方案,需要通過優化器進行選擇,選擇執行成本(包括IO/CPU成本)
最低的方案。 在一條單表查詢語句真正執行之前,MySQL的查詢優化器會找出執行該語句所有可能使用的方案,對比之後找出成本最低的方案。這個成本最低的方案就是所謂的執行計劃。
Mysql每個表維護了一系列的統計信息SHOW TABLE STATUS LIKE 'table_name'
。
優化過程大致如下:
1、根據搜索條件,找出所有可能使用的索引
2、計算全表掃描的代價
3、計算使用不同索引執行查詢的代價 先分析使用唯一二級索引的成本,再分析使用普通索引的成本
4、對比各種執行方案的代價,找出成本最低的那一個
連接查詢
小表驅動大表
事務
事務的隔離級別
READ UNCOMMITTED
:未提交讀。髒讀,不可重複讀,幻讀
READ COMMITTED
:已提交讀。不可重複讀,幻讀
REPEATABLE READ
:可重複讀。幻讀
SERIALIZABLE
:可串行化。保證所有的情況不會發生(鎖表)
- 髒讀:一個事務讀到了另一個未提交事務修改過的數據
- 不可重複讀:是指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務也訪問該同一數據。那麼,在第一個事務中的兩 次讀數據之間,由於第二個事務的修改,那麼
第一個事務兩次讀到的的數據可能是不一樣
的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱爲是不可重複讀。 - 幻讀:是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。 同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,以後就會發生
操作第一個事務的用戶發現表中還有沒有修改的數據行
,就好象 發生了幻覺一樣。