首頁  >  文章  >  資料庫  >  mysql 聯合索引有什麼好處? 聯合索引的意義

mysql 聯合索引有什麼好處? 聯合索引的意義

零下一度
零下一度原創
2017-05-08 14:58:376939瀏覽

mysql 裡創建‘聯合索引’的意義

問題?
因為什麼需求,要建立『聯合索引』?最實際好處在於什麼?如果是為了更快查詢到數據,有單列索引不是Ok?為什麼有‘聯合索引’的存在?

簡單的說有兩個主要原因:

  • "一個頂三個」。建了一個(a,b,c)的複合索引,那麼實際上等於建了(a),(a,b),(a,b,c)三個索引,因為每多一個索引,都會增加寫入運算的開銷和磁碟空間的開銷。對於大量資料的表,這可是不小的開銷!

  • 覆寫索引。同樣的有複合索引(a,b,c),如果有如下的sql: select a,b,c from table where a=1 and b = 1。那麼MySQL可以直接透過遍歷索引取得數據,而無需回表,這減少了很多的隨機io操作。減少io操作,特別的隨機io其實是dba主要的最佳化策略。所以,在真正的實際應用中,覆蓋索引是主要的提升效能的最佳化手段之一

  • #索引列越多,透過索引篩選出的資料越少。有1000W條數據的表,有以下sql:select from table where a = 1 and b =2 and c = 3,假設假設每個條件可以篩選出10%的數據,如果只有單值索引,那麼透過此索引能篩選出1000W10%=100w 條數據,然後再回表從100w條數據中找到符合b=2 and c= 3的數據,然後再排序,再分頁 ;如果是複合索引,透過索引篩選出1000w 10% 10% *10%=1w,然後再排序、分頁,哪個更有效率,一眼便知

#如下的有a,b,c 三個key的table

create table test(
    a int,
    b int,
    c int,
);

如果我們
需要執行很多的類似於select * from test where a=10 , b>50, c>20
這類的組合查詢 那麼,我們可能需要建立包含[a,b,c] 的共同索引,而單獨的[a][ b] [c]上的索引是不夠的。 (可以把一個索引想像成sorted list).創建了(a,b,c)的索引相當於按照a,b,c 排序(排序規則是

  if(X.a>Y.a)
    return '>';
  else if(X.a<Y.a)
    return &#39;<&#39;;
   else if(X.b>Y.b)
    return &#39;>&#39;;
   else if (X.b<Y.b)
    return &#39;<&#39;;
   else if (X.c>Y.c)
    return  &#39;>&#39;
   else if (X.c<Y.c)
    return  &#39;<&#39;
   esle
    return &#39;==&#39;
)

和分別依a 排序分別依b排序分別依照c排序是不一樣的。 ,c)的聯合索引,查詢效率如下:

  优: select * from test where a=10 and b>50
  差: select * from test where a>50

  优: select * from test order by a
  差: select * from test order by b
  差: select * from test order by c

  优: select * from test where a=10 order by a
  优: select * from test where a=10 order by b
  差: select * from test where a=10 order by c

  优: select * from test where a>10 order by a
  差: select * from test where a>10 order by b
  差: select * from test where a>10 order by c

  优: select * from test where a=10 and b=10 order by a
  优: select * from test where a=10 and b=10 order by b
  优: select * from test where a=10 and b=10 order by c

  优: select * from test where a=10 and b=10 order by a
  优: select * from test where a=10 and b>10 order by b
  差: select * from test where a=10 and b>10 order by c

下面用圖示的方式來表示

三注意

在mysql中若列是varchar 類型,請不要使用int類型去存取

如下

zz_deals表中product_id 是varchar類型

mysql> explain select * from zz_deals where  qq_shop_id = 64230 and product_id = &#39;38605906667&#39; ;+----+-------------+-------------+------+------------------------------+------------------------------+---------+-------------+------+-------------+| id | select_type | table       | type | possible_keys                | key                          | key_len | ref         | rows | Extra       |+----+-------------+-------------+------+------------------------------+------------------------------+---------+-------------+------+-------------+|  1 | SIMPLE      | zz_deals | ref  | by_product_id_and_qq_shop_id | by_product_id_and_qq_shop_id | 156     | const,const |    1 | Using where |+----+-------------+-------------+------+------------------------------+------------------------------+---------+-------------+------+-------------+1 row in set (0.00 sec)
mysql> explain select * from zz_deals where  qq_shop_id = 64230 and product_id = 38605906667 ;+----+-------------+-------------+------+------------------------------+------+---------+------+------+-------------+| id | select_type | table       | type | possible_keys                | key  | key_len | ref  | rows | Extra       |+----+-------------+-------------+------+------------------------------+------+---------+------+------+-------------+|  1 | SIMPLE      | zz_deals | ALL  | by_product_id_and_qq_shop_id | NULL | NULL    | NULL |   17 | Using where |+----+-------------+-------------+------+------------------------------+------+---------+------+------+-------------+1 row in set (0.00 sec)

宣傳語

歷經兩個半月的準備,三次大改版,十七次小改版。有故事的影片。 #1. 

免費mysql線上影片教學

##2. MySQL最新手冊教學

3. 資料庫設計那些事

以上是mysql 聯合索引有什麼好處? 聯合索引的意義的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn