mysql複合式索引與欄位順序

來源:互聯網
上載者:User

下列轉自:http://www.tech-q.cn/archiver/tid-11673.html

很多時候,我們在mysql中建立了索引,但是某些查詢還是很慢,根本就沒有使用到索引!
一般來說,可能是某些欄位沒有建立索引,或者是複合式索引中欄位的順序與查詢語句中欄位的順序不符。

看下面的例子:
假設有一張訂單表(orders),包含order_id和product_id二個欄位。
一共有31條資料。符合下面語句的資料有5條。

執行下面的sql語句:
select product_id
from orders
where order_id in (123, 312, 223, 132, 224);

這條語句要mysql去根據order_id進行搜尋,然後返回匹配記錄中的product_id。

所以複合式索引應該按照以下的順序建立:
create index orderid_productid on orders(order_id, product_id)
mysql> explain select product_id from orders where order_id in (123, 312, 223, 132, 224) \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: orders
         type: range
possible_keys: orderid_productid
          key: orderid_productid
      key_len: 5
          ref: NULL
         rows: 5
        Extra: Using where; Using index
1 row in set (0.00 sec)

可以看到,這個複合式索引被用到了,掃描的範圍也很小,只有5行。

如果把複合式索引的順序換成product_id, order_id的話,
mysql就會去索引中搜尋 *123 *312 *223 *132 *224,必然會有些慢了。
mysql> create index orderid_productid on orders(product_id, order_id);                                                      
Query OK, 31 rows affected (0.01 sec)
Records: 31  Duplicates: 0  Warnings: 0

mysql> explain select product_id from orders where order_id in (123, 312, 223, 132, 224) \G

*************************** 1. row ***************************

           id: 1
  select_type: SIMPLE
        table: orders
         type: index
possible_keys: NULL
          key: orderid_productid
      key_len: 10
          ref: NULL
         rows: 31
        Extra: Using where; Using index
1 row in set (0.00 sec)

這次索引搜尋的效能顯然不能和上次相比了。

rows:31,我的表中一共就31條資料。

索引被使用部分的長度:key_len:10,比上一次的key_len:5多了一倍。

不知道是這樣在索引裡面尋找速度快,還是直接去全表掃描更快呢?
mysql> alter table orders add modify_a char(255) default 'aaa';
Query OK, 31 rows affected (0.01 sec)
Records: 31  Duplicates: 0  Warnings: 0

mysql>
mysql>
mysql> explain select modify_a from orders where order_id in (123, 312, 223, 132, 224) \G         
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: orders
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 31
        Extra: Using where
1 row in set (0.00 sec)

這樣就不會用到索引了。 剛才是因為select的product_id與where中的order_id都在索引裡面的。

為什麼要建立複合式索引呢?這麼簡單的情況直接建立一個order_id的索引不就行了嗎?
如果只有一個order_id索引,沒什麼問題,會用到這個索引,然後mysql要去磁碟上的表裡面取到product_id。

如果有複合式索引的話,mysql可以完全從索引中取到product_id,速度自然會快。

再多說幾句複合式索引的最左優先原則:
複合式索引的第一個欄位必須出現在查詢組句中,這個索引才會被用到。
如果有一個複合式索引(col_a,col_b,col_c)

下面的情況都會用到這個索引:
col_a = "some value";
col_a = "some value" and col_b = "some value";
col_a = "some value" and col_b = "some value" and col_c = "some value";
col_b = "some value" and col_a = "some value" and col_c = "some value";

對於最後一條語句,mysql會自動最佳化成第三條的樣子~~。

下面的情況就不會用到索引:
col_b = "aaaaaa";
col_b = "aaaa" and col_c = "cccccc";

下列轉自:http://hi.baidu.com/liuzhiqun/blog/item/4957bcb1aed1b5590823023c.html

通過執行個體理解單列索引、多列索引以及最左首碼原則

執行個體:現在我們想查出滿足以下條件的使用者id:
mysql>SELECT `uid` FROM people WHERE lname`='Liu'  AND `fname`='Zhiqun' AND `age`=26
因為我們不想掃描整表,故考慮用索引。

單列索引:
ALTER TABLE people ADD INDEX lname (lname);
將lname列建索引,這樣就把範圍限制在lname='Liu'的結果集1上,之後掃描結果集1,產生滿足fname='Zhiqun'的結果集2,再掃描結果集2,找到 age=26的結果集3,即最終結果。

由 於建立了lname列的索引,與執行表的完全掃描相比,效率提高了很多,但我們要求掃描的記錄數量仍舊遠遠超過了實際所需 要的。雖然我們可以刪除lname列上的索引,再建立fname或者age 列的索引,但是,不論在哪個列上建立索引搜尋效率仍舊相似。

2.多列索引:
ALTER TABLE people ADD INDEX lname_fname_age (lame,fname,age);
為了提高搜尋效率,我們需要考慮運用多列索引,由於索引檔案以B-Tree格式儲存,所以我們不用掃描任何記錄,即可得到最終結果。

註:在mysql中執行查詢時,只能使用一個索引,如果我們在lname,fname,age上分別建索引,執行查詢時,只能使用一個索引,mysql會選擇一個最嚴格(獲得結果集記錄數最少)的索引。

3.最左首碼:顧名思義,就是最左優先,上例中我們建立了lname_fname_age多列索引,相當於建立了(lname)單列索引,(lname,fname)複合式索引以及(lname,fname,age)複合式索引。

註:在建立多列索引時,要根據業務需求,where子句中使用最頻繁的一列放在最左邊。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.