MySQL的索引策略(2)

上文提到了用自增主鍵作聚簇索引列,能夠方便插入操做。但高併發場景下,主鍵的上界集中了全部的插入,可能致使間隙鎖競爭(間隙鎖是innodb中行鎖的一種, 可是這種鎖鎖住的卻不止一行數據,他鎖住的是多行,是一個數據範圍。間隙鎖的主要做用是爲了防止出現幻讀;對符合條件的已有數據記錄的索引項加鎖;對於鍵值在條件範圍內但並不存在的記錄,叫作「間隙(GAP)」,InnoDB也會對這個「間隙」加鎖,這種鎖機制就是所謂的間隙鎖(Next-Key鎖))。同時,自增字段的鎖機制也可能成爲熱點。mysql

  • 覆蓋索引

指包含了全部須要查詢字段的索引。覆蓋索引的優點以下sql

  1. 下降數據訪問量。索引列數據一般遠少於整行數據。
  2. 優化範圍查詢。由於索引是按順序創建的。
  3. 內存中保存索引,因此可避免訪問磁盤/產生系統調用。
  4. 聚簇索引中,二級主鍵的覆蓋查詢能夠直接在葉子節點讀取數據,從而避免了再次訪問聚簇索引取值的過程。這個是覆蓋索引最多見的用途

覆蓋索引的核心是:索引結構保存相關列的值。因此,通常用在B+樹索引。併發

  • 索引掃描排序

​​​​​​​前篇提到,索引的三個用途是:SELECT、ORDER BY、GROUP BY。高併發

若是索引不能覆蓋全部列,則讀取數據的過程是:...->索引中讀取n行相關信息->查找n行->索引讀取n+1行數據->...。這樣比順序掃描全表還慢。因此使用索引掃描排序須知足條件:性能

  1. 索引列的順序與ORDER BY的順序徹底一致。col1, col2..
  2. 索引排序方向與ORDER BY的排序方向一致。ASC, DESC。
  3. 最左前綴。
  4. 多表關聯時,ORDER BY的字段必須都在第一張表。
  • 合理冗餘索引
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在二級索引上使用共享鎖,在訪問主鍵索引時用排他鎖。因此,在二級索引訪問時,其餘事務依然能夠寫入數據,那麼就沒法使用覆蓋索引。

  • 其餘細節
  1. ​​​​​​​把最常出現的where的列放在最左。在不須要該篩選條件時,能夠IN (全部值)以知足最左前綴。在創建合理索引的同時,也考慮針對索引優化查詢。
  2. 範圍查詢儘可能放在最右。由於範圍索引以後的索引都會失效。多個範圍查詢時,特別須要避免範圍查詢;替代方案是用窮舉 IN方案,此時要注意,多個IN之間,在優化時作笛卡爾積,產生m*n*...個=條件的查詢;不能窮舉的狀況(datatime >= ,最近訪問),能夠設置標誌列,實時更新,在業務上避免使用範圍查詢。
  3. 優化排序。
    mysql> SELECT <cols> FROM profiles WHERE sex='M' ORDER BY rating LIMIT 10;

    這個查詢中,可建立(sex, rating)索引幫助排序,不要侷限於where後的條件。

  4. 翻頁查詢

    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中創建的索引)快速查詢到主鍵,而後取值。

相關文章
相關標籤/搜索