mysql的索引掃描排序與排序操作
目錄
一、排序方式
mysql有兩種方式可以生產有序的結果:
1、通過排序操作;
2、按索引順序掃描;
二、判斷
通過explain出來的type列的值爲“index”,則說明mysql使用了索引掃描來做排序。
掃描索引本身是很快的,因爲只需要從一條索引記錄移動到緊接着的下一條記錄。但如果索引不能覆蓋查詢所需的全部列,那就不得不每掃描一條索引記錄就都回表查詢一次對應的行,這基本上都是隨機I/O.
三、規則
1)只有當索引的列順序和order by 子句的順序完全一致,並且所有列的排序方向(倒序或正序)都一樣時,mysql才能夠使用索引來對結果做排序;
2)如果查詢需要關聯多張表,則只有當order by 子句引用的字段全部爲第一個表時,才能使用索引做排序;
3)order by 子句需要滿足索引的最左前綴的要求
四、舉例
建表
create table rental (
...
primary key(rental_id),
unique key rental_date (rental_date, inventory_id, customer_id),
key idx_fk_inventory_id (inventory_id),
key idx_fk_customer_id (customer_id),
key idx_fk_staff_id (staff_id)
);
搜索排序:
select rental_id, staff_id from rental
wherer rental_date = '2005-05-25' order by inventory_id, customer_id;
即使order by 子句不滿足索引的最左前綴的要求,也可以用於查詢排序,這是因爲索引的第一列被指定爲一個常數。
可以視爲將查詢列和排序列組合在一起,形成索引的最左前綴。
wherer rental_date = '2005-05-25' order by inventory_id desc;
下面也符合,order by 使用的兩列是索引的最左前綴。
wherer rental_date > '2005-05-25' order by rental_date, inventory_id;
下面試一些不能使用索引做排序的查詢:
wherer rental_date = '2005-05-25' order by inventory_id desc, customer_id asc;(兩種不同的排序方向)
wherer rental_date = '2005-05-25' order by inventory_id, staff_id;(order by引用一個不再索引中的列)
wherer rental_date = '2005-05-25' order by customer_id;(where和order by中的列無法組合成索引的最左前綴)
wherer rental_date > '2005-05-25' order by inventory_id, customer_id;(查詢索引是範圍條件)
wherer rental_date = '2005-05-25' and inventory_id in(1, 2) order by customer_id;
(inventory_id 列上有多個等於條件,對於排序來說,這也是一種範圍查詢)