一次復合索引的調整

一次復合索引的調整

 

表test如下:

 

| Field | Type | Null | Key | Default | Extra |

+————-+———————–+——+—–+———+—————-+

| pid | int(10) unsigned | NO | PRI | NULL | auto_increment |

| tid | mediumint(8) unsigned | NO | MUL | 0 | |

| showtime | int(11) | YES | | 0 | |

  www.aiwalls.com  

數據量200w+

 

原來有個復合索引建立在tid和showtime上的。

現有個sql

SELECT * FROM test  WHERE AND tid='47992' AND pid >=1660250 and showtime>0  ORDER BY p.showtime,p.pid LIMIT 0, 40;

於是將索引修改如下(tid為最左前綴不能改,有別的sql用到tid+showtime):

ALTER TABLE test ADD INDEX idx_tid_showtime_pid(tid,showtime,pid);

執行sql效率很低,請看explain  www.aiwalls.com  

 

+—-+————-+—————-+——-+———————-+———————-+———+——+——–+————-+

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+—-+————-+—————-+——-+———————-+———————-+———+——+——–+————-+

| 1 | SIMPLE | test | range | idx_tid_showtime_pid | idx_tid_showtime_pid | 8 | NULL | 123444 | Using where |

+—-+————-+—————-+——-+———————-+———————-+———+——+——–+————-+

 

感覺效率依然很低,通過slow-log記錄可以看到執行時間在0.7秒以上。

測試瞭下去掉showtime條件後隻使用tid和pid的復合索引效率是很高的,於是再次修改索引:

ALTER TABLE test ADD INDEX idx_tid_pid_showtime(tid,pid,showtime);

這樣效率大大提高,執行時間降到瞭0.1以下。  www.aiwalls.com  

 

+—-+————-+——-+——-+—————————————————————————————+———————-+———+——+——+—————————–+

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+—-+————-+——-+——-+—————————————————————————————+———————-+———+——+——+—————————–+

| 1 | SIMPLE | test | range | idx_tid_showtime_pid,idx_tid_pid_showtime | idx_tid_pid_showtime | 12 | NULL | 3290 | Using where; Using filesort |

+—-+————-+——-+——-+—————————————————————————————+———————-+———+——+——+——

 

    以上問題,從我個人理解上是這樣的,idx_tid_showtime_pid(tid,showtime,pid)這條索引滿足瞭使用索引order by的條件,所以需要掃描123444行數據。

    而 idx_tid_pid_showtime(tid,pid,showtime)這條索引的列順序和order by的順序不一樣,排序無法使用索引,而where條件使用索引效率很好,隻掃描瞭3290行數據,即使加上排序的時間也很快。

 

    由此可見索引的添加也不能一味的以字段順序去適應排序的順序,雖然省略瞭排序所花的時間,但是在其他的開銷上遠大於少量數據排序帶來的影響。

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *