上文提到了用自增主鍵作聚簇索引列,能夠方便插入操做。但高併發場景下,主鍵的上界集中了全部的插入,可能致使間隙鎖競爭(間隙鎖是innodb中行鎖的一種, 可是這種鎖鎖住的卻不止一行數據,他鎖住的是多行,是一個數據範圍。間隙鎖的主要做用是爲了防止出現幻讀;對符合條件的已有數據記錄的索引項加鎖;對於鍵值在條件範圍內但並不存在的記錄,叫作「間隙(GAP)」,InnoDB也會對這個「間隙」加鎖,這種鎖機制就是所謂的間隙鎖(Next-Key鎖))。同時,自增字段的鎖機制也可能成爲熱點。mysql
指包含了全部須要查詢字段的索引。覆蓋索引的優點以下sql
覆蓋索引的核心是:索引結構保存相關列的值。因此,通常用在B+樹索引。併發
前篇提到,索引的三個用途是:SELECT、ORDER BY、GROUP BY。高併發
若是索引不能覆蓋全部列,則讀取數據的過程是:...->索引中讀取n行相關信息->查找n行->索引讀取n+1行數據->...。這樣比順序掃描全表還慢。因此使用索引掃描排序須知足條件:性能
CREATE TABLE test ( ID INT NOT NULL PRIMARY KEY, A INT NOT NULL, B text NOT NULL, UNIQUE(ID), INDEX(ID) ) ENGINE=InnoDB;
上述表的主鍵限制、惟一限制都是經過索引實現的。因此,這張表的ID列上,存在三個索引。這種冗餘是沒有意義的。優化
或者說,把(A)索引擴展爲(A, ID),這樣也是沒有意義的。聚簇索引的二級索引的葉節點,自己就包含主鍵信息。spa
SELECT A,B from test where A=2;
對上述查詢,若是咱們擴展索引(A)爲(A, B),就能夠利用覆蓋索引,加速查詢。但B字段很長,會致使只取A字段時性能降低。此時,能夠同時保留(A)和(A, B)索引,雖然對A列來講是冗餘索引,但總體查詢的性能提高了 。code
減小鎖的行數,有兩個直接好處:1.減小加鎖開銷 2.減小事務間的競爭。排序
InnoDB在訪問行時纔會加鎖;因此若是索引能幫助篩選掉不須要訪問的行,就能減小加鎖量。索引
不然,InnoDB須要作全表掃描,鎖住全部的行。
InnoDB在二級索引上使用共享鎖,在訪問主鍵索引時用排他鎖。因此,在二級索引訪問時,其餘事務依然能夠寫入數據,那麼就沒法使用覆蓋索引。
mysql> SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 10;
這個查詢中,可建立(sex, rating)索引幫助排序,不要侷限於where後的條件。
翻頁查詢
mysql> SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 100000, 10; mysql> SELECT <cols> FROM profiles INNER JOIN ( -> SELECT <primary key cols> FROM profiles -> WHERE x.sex='M' ORDER BY rating LIMIT 100000, 10 -> ) AS x USING(<primary key cols>);
偏移量越大,會須要更多的掃描來丟棄不須要的數據;能夠在業務上限制翻頁數量。下面一條是一種優化查詢,先用覆蓋索引(3中創建的索引)快速查詢到主鍵,而後取值。