mysql使用索引扫描做排序_「Mysql索引原理(八)」使用索引扫描做排序
MySQL有兩種方式可以生成有序的結果:通過排序操作;或者按索引順序掃描;如果explain出來的type列的值為index,則說明MySQL使用了索引掃描來做排序。
掃描索引本身是很快的,因為只需要從一條索引記錄移動到緊接著的下一條記錄。但如果索引不能覆蓋查詢所需的全部列,那就不得不每掃描一條索引記錄就得回表查詢一次對應的行了。這基本上都是隨機I/O,因此按索引順序讀取數據的速度通常要比順序地全表掃描慢,尤其是在I/O密集型的工作負載時。
MySQL可以使用同一個索引既滿足排序,又用于查找行。因此,如果可能,設計索引時應該盡可能地同時滿足這兩個任務,這樣是最好的。
只有當索引的順序和ORDER BY子句的順序完全一致,并且所有列的排序方向都一樣時,MySQL才能使用索引結果來做排序。如果查詢需要關聯多張表,則只有當ORDER BU子句引用的字段全部為第一個表時,才能使用索引做排序。ORDER BY子句和查找型查詢的限制是一樣的:需要滿足索引的最左前綴的要求;否則,MySQL都需要執行排序操作,而無法利用索引排序。
有一種情況ORDER BY子句可以不滿足索引的最左前綴的要求,就是前導列為常量的時候。如果WHERE子句或者JOIN子句中對這些列指定了常量,就可以彌補索引的不足。
如,
CREATE TABLE `sakila` (
`rental_id` int(10) NOT NULL AUTO_INCREMENT,
`rental_date` date DEFAULT NULL,
`inventory_id` int(10) DEFAULT NULL,
`customer_id` int(10) DEFAULT NULL,
`staff_id` int(10) DEFAULT NULL,
PRIMARY KEY (`rental_id`),
UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`) USING BTREE,
KEY `inventory` (`inventory_id`) USING BTREE,
KEY `customer` (`customer_id`) USING BTREE,
KEY `staff` (`staff_id`) USING BTREE
) ENGINE=InnoDB ;
MySQL可以使用rental_date索引為下面的查詢做排序,從explain中可以看到有沒有出現文件排序操作:
explain select rental_id,staff_id from sakila where rental_date='2019-10-10' order by inventory_id,customer_id
即使order by子句不滿足索引的最前左綴的要求,也可以喲用于查詢排序,這是因為索引的第一列被指定為一個常數。
還有更多可以使用索引做排序的查詢示例。下面這個查詢可以利用索引排序,是因為查詢為索引的第一列提供了常量條件,而是用第二列進行排序,將兩列組合在一起,就形成了索引的最左前綴:
explain select rental_id,staff_id from sakila where rental_date='2019-10-10' order by inventory_id desc
explain select rental_id,staff_id from sakila where rental_date > '2019-10-10' order by rental_date,inventory_id
這列查詢則不能使用索引排序:
1、排序方向不同,而索引列是正序排序
... where rental_date='2019-10-10' order by inventory_id desc,customer_id asc
2、order by子句引用了一個不再索引中的列
... where rental_date='2019-10-10' order by inventory_id desc,staff_id
3、where和order by中的列無法組合成索引的最左前綴
... where rental_date='2019-10-10' order by customer_id asc
4、wehre子句在索引列的第一列上市范圍條件,所以MySQL無法使用索引的其余列
... where rental_date>'2019-10-10' order by inventory_id desc,customer_id
5、在inventory_id列上有多個等于條件。對于排序來說,這也是一種范圍查詢
... where rental_date='2019-10-10' and inventory_id in(1,2) order by customer_id
總結
以上是生活随笔為你收集整理的mysql使用索引扫描做排序_「Mysql索引原理(八)」使用索引扫描做排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 橄榄树根的功效与作用、禁忌和食用方法
- 下一篇: dapperpoco mysql_Dap