mysql 里創建‘聯合索引’的意義
問題?
因為什么需求,要創建‘聯合索引’?最實際好處在于什么?如果是為了更快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的數據,然后再排序,再mysql;如果是復合索引,通過索引篩選出1000w 10% 10% *10%=1w,然后再排序、分頁,哪個更高效,一眼便知
如下的有a,b,c 三個mysql的table
create?table?test( ????a?int, ????b?int, ????c?int, );
如果我們
需要執行很多的類似于 select * from test where a=10, b>50, c>20
這類的mysql 那么,我們可能需要創建 包含[a,b,c] 的聯合索引,而單獨的[a][b] [c]上的索引是不夠的。(可以把一個索引想象成 mysqled list).創建了 (a,b,c)的索引相當于 按照a,b,c 排序(排序規則是
??if(X.a>Y.a) ????return?'>'; ??else?if(X.a<y.a>Y.b) ????return?'>'; ???else?if?(X.b<y.b>Y.c) ????return??'>' ???else?if?(X.c<y.c><p>和分別 按a 排序 分別按b排序 分別按照c排序是不一樣的。</p> <p>其中 a b c 的順序也很重要,有時可以是a c b,或者b c a等等。<br>如果創建 (a,b,c)的聯合索引,查詢效率如下:</p> <pre class="brush:sql;toolbar:false;">??優:?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?=?'38605906667'?;+----+-------------+-------------+------+------------------------------+------------------------------+---------+-------------+------+-------------+|?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)
宣傳語
歷經兩個半月的準備,三次大改版,十七次小改版。le1024終于要和大家見面了。
le1024每天推薦1~3段,有趣、有愛、有故事的視頻。
為您工作、學習、生活之余增加一點快樂的感覺。
【相關推薦】
1.?mysql
2.?mysql
3.?mysql