給表加索引時,其中一些查詢會用到order by ,group by之類的,在低版本(有ICP之前版本)中可能會遇到一種情況,where查詢用到索引,那麼order by就無法用到索引,當然我們可以創建聯合索引,那麼什麼情況下創建聯合索引是有效的呢?可以通過explain 看order by是否有file sort,where是否使用到了索引。
那麼order by 如何避免file sort,之後的索引應該如何創建,在這裡做下總結:1、根據索引查詢數據後,是否還需要排序,如果需要就會產生file sort,否則不會;所以在創建索引的時候需要特別注意,能將避免file sort的盡可能通過創建索引來解決,無法解決的就改sql,或者考慮其它辦法。但需要考慮file sort不一定會慢,主要還得看數據量,有些情況還是允許file sort的,file sort也分為內存和磁盤,只有在sort buffer裝載不下的情況,才能會磁盤中去進行分塊排序。
2、聯合索引使用長度需要注意,看聯合索引用到了幾列,什麼樣了sql會用到索引的程度。如,a為范圍查詢,<、>、!=,那麼b就無法使用到(不支持ICP情況)。只能當前綴列為= 、<=或者>=時,後面的列才會用到。
如下是聯合索引idx_a_b_c(a,b,c)各種查詢條件下是否有file sort,另外使用到的索引情況。(mysql版本,5.1.63)
思考:
create table ttt (
id int(10) NOT NULL AUTO_INCREMENT,
uid int(10) NOT NULL,
status tinyint(2) NOT NULL,
ordertime int(11) NOT NULL,
view varchar(20) NOT NULL
primary key(id),
key idx_status_rodertime(status,ordertime),
key idx_uid(uid))engine = innodb;
)engine = innodb;
此表有3000多w.其中uid和status,ordertime的distinct值。
mysql> select count(distinct uid) from ttt;
+------------------------+
| count(distinct uid) |
+------------------------+
| 9112 |
+------------------------+
1 row in set (51.89 sec)
mysql> select count(distinct status,ordertime) from ttt;
+--------------------------------+
| count(distinct status,ordertime) |
+--------------------------------+
| 5424 |
+--------------------------------+1 row in set (51.77 sec)
1 row in set (51.77 sec)
上表有這樣的一個查詢 :
select * from ttt where status=6 and ordertime >=1451012466 and ordertime <=1451016066 order by uid asc limit 100;
在目前這種情況下,如何優化這條sql,為什麼?(數據庫版本不限)