8.3.1 MySQL是如何使用索引的

原文:https://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html

8.3.1 MySQL是如何使用索引的

索引能夠通過特定列上的值快速查找到數據行。如果沒有索引,MySQL必須從第一行順序讀取全表數據才能查找到相關的數據,表越大,越消耗資源。如果在要查詢的列上有索引,MySQL可以快速定位到數據而不用掃描全部數據,這比順序讀取表數據要快很多很多。

大多數MySQL索引(PRIMARY KEY, UNIQUE, INDEX, and FULLTEXT)使用B-trees結構存儲.空間索引使用R-trees,MEMORY表還支持hash索引;InnoDB使用倒排列表實現的全文索引(FULLTEXT indexes).

通常,我們需要按下面討論的方式使用索引。hash索引的有點特殊,具體請參考Section 8.3.8, “Comparison of B-Tree and Hash Indexes”

MySQL使用索引規則:

  • 爲了快速的找到where條件匹配的數據.
  • 爲了排除某些行:如果可以選擇多個索引,MySQL一般會選擇匹配行最少的那個索引.也就是最selective的索引。

    selective:數據分佈的一個屬性,數值=column distinct(values)/table rows。數值越大,使用該索引查詢效率越高。如果你(或優化器)預估到使用某索引匹配到的行更少,則使用這個索引效率越高。

  • 如果一個表有多列索引,優化器會使用最左匹配原則使用該索引.舉例,如果你有一個三列索引(col1, col2, col3),這個索引可以匹配(col1), (col1, col2), 和 (col1, col2, col3)搜索條件.更多信息Section 8.3.5, “Multiple-Column Indexes”.
  • 使用join關聯多表查詢時,如果索引使用的相同類型同等長度的列,執行會更快.在此場景下,varchar和char長度相同時,MySQL會認爲兩者是相同的.比如,VARCHAR(10) 和 CHAR(10) 長度相同,但是VARCHAR(10) 和 CHAR(15)不同。

    比較兩個字符類型的列時,它們使用的字符集必須相同.否則不會使用索引.

    比較兩個不同類型的列時,如果類型不能直接比較(必須使用conversion函數)則不會使用索引。比如數字1,它與字符’1’, ’ 1’, ‘00001’, or ‘01.e1’相等。但這兩個類型不能直接比較,所以不能使用索引。

  • 爲了在建立了索引的列key_col上查詢MIN() 或 MAX()值,當查詢條件使用 WHERE key_part_N =固定值,且索引中key_col前面的key都使用了固定值,此時預處理器會優化這個sql。In this case, MySQL does a single key lookup for each MIN() or MAX() expression and replaces it with a constant. If all expressions are replaced with constants, the query returns at once.

    SELECT MIN(key_part2),MAX(key_part2)
    FROM tbl_name WHERE key_part1=10;
  • 如果對一個表使用最左匹配的索引排序或分組時(比如, ORDER BY key_part1, key_part2),如果所有的類都是按DESC排序,索引對使用倒序讀取.See Section 8.2.1.13, “ORDER BY Optimization”, and Section 8.2.1.14, “GROUP BY Optimization”.

  • 在有些情況下,一個查詢語句直接從索引中取值而不用從數據行上取值.(如果一個索引包含了查詢的所有列,這個索引被稱爲覆蓋索引covering index.)如果一個查詢使用到的列都包含在某些索引上,這個查詢會從索引tree上獲取數據,這將會極大的提高查詢速度:

    SELECT key_part3 FROM tbl_name
    WHERE key_part1=1

    covering index
    An index that includes all the columns retrieved by a query. Instead of using the index values as pointers to find the full table rows, the query returns values from the index structure, saving disk I/O. InnoDB can apply this optimization technique to more indexes than MyISAM can, because InnoDB secondary indexes also include the primary key columns. InnoDB cannot apply this technique for queries against tables modified by a transaction, until that transaction ends.

    Any column index or composite index could act as a covering index, given the right query. Design your indexes and queries to take advantage of this optimization technique wherever possible.

對一個數據量小的表,或需要查詢大部分甚至全部的大表,索引是不重要的.當一個查詢需要查詢一個大部分數據時,順序讀取數據會比使用索引查詢更快.因爲順序讀取減少了磁盤尋址,儘管並不是所有的行都符合查詢結果.

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