mysql有兩種方式可以生成有序的結果:通過排序操作或者按索引順序掃瞄,如果explain出來的type列的值為index,則說明mysql使用了索引掃瞄來做排序
掃瞄索引本身是很快的,因為只需要從一條索引記錄移動到緊接著的下一條記錄。但如果索引不能覆蓋查詢所需的全部列,那麼就不得不每掃瞄一條索引記錄就得回表查詢一次對應的行,這基本都是隨機io,因此按索引順序讀取資料的速度通常要比順序地全表掃瞄慢
mysql可以使用同乙個索引即滿足排序,又用於查詢行,如果可能的話,設計索引時應該盡可能地同時滿足這兩種任務。
只有當索引的列順序和order by子句的順序完全一致,並且所有列的排序方式都一樣時,mysql才能夠使用索引來對結果進行排序,如果查詢需要關聯多張表,則只有當orderby子句引用的字段全部為第一張表時,才能使用索引做排序。order by子句和查詢型查詢的限制是一樣的,需要滿足索引的最左字首的要求,否則,mysql都需要執行順序操作,而無法利用索引排序
--sakila資料庫中rental表在rental_date,inventory_id,customer_id上有rental_date的索引
--使用rental_date索引為下面的查詢做排序
explain
select rental_id,staff_id from rental where rental_date=
'2005-05-25'
order
by inventory_id,customer_id\g**
****
****
****
****
****
****
*1.row***
****
****
****
****
****
****
id: 1
select_type: ******
table: rental
partitions: null
type: ref
possible_keys: rental_date
key: rental_date
key_len: 5
ref: const
rows: 1
filtered: 100.00
extra: using
index condition
1row
inset
,1 warning (
0.00 sec)
--order by子句不滿足索引的最左字首的要求,也可以用於查詢排序,這是因為所以你的第一列被指定為乙個常數
--該查詢為索引的第一列提供了常量條件,而使用第二列進行排序,將兩個列組合在一起,就形成了索引的最左字首
explain
select rental_id,staff_id from rental where rental_date=
'2005-05-25'
order
by inventory_id desc\g**
****
****
****
****
****
****
*1.row***
****
****
****
****
****
****
id: 1
select_type: ******
table: rental
partitions: null
type: ref
possible_keys: rental_date
key: rental_date
key_len: 5
ref: const
rows: 1
filtered: 100.00
extra: using
where
1row
inset
,1 warning (
0.00 sec)
--下面的查詢不會利用索引
explain
select rental_id,staff_id from rental where rental_date>
'2005-05-25'
order
by rental_date,inventory_id\g**
****
****
****
****
****
****
*1.row***
****
****
****
****
****
****
id: 1
select_type: ******
table: rental
partitions: null
type: all
possible_keys: rental_date
key: null
key_len: null
ref: null
rows: 16005
filtered: 50.00
extra: using
where
;using filesort
--該查詢使用了兩中不同的排序方向,但是索引列都是正序排序的
explain
select rental_id,staff_id from rental where rental_date>
'2005-05-25'
order
by inventory_id desc
,customer_id asc\g**
****
****
****
****
****
****
*1.row***
****
****
****
****
****
****
id: 1
select_type: ******
table: rental
partitions: null
type: all
possible_keys: rental_date
key: null
key_len: null
ref: null
rows: 16005
filtered: 50.00
extra: using
where
;using filesort
1row
inset
,1 warning (
0.00 sec)
--該查詢中引用了乙個不再索引中的列
explain
select rental_id,staff_id from rental where rental_date>
'2005-05-25'
order
by inventory_id,staff_id\g**
****
****
****
****
****
****
*1.row***
****
****
****
****
****
****
id: 1
select_type: ******
table: rental
partitions: null
type: all
possible_keys: rental_date
key: null
key_len: null
ref: null
rows: 16005
filtered: 50.00
extra: using
where
;using filesort
1row
inset
,1 warning (
0.00 sec)
MySQL 使用索引掃瞄來做排序
mysql有兩種方式可以生成有序的結果 通過排序操作 或者按照索引順序掃瞄 如果explain 出來的結果的type列的值為 index 則說明mysql使用了索引掃瞄來做排序 不要和extra列的 using index 搞混 掃瞄索引本身是很快的,因為只需要從一條索引記錄移動到緊接著的下一條記錄...
mysql索引 之使用索引掃瞄做排序
今天看了 高效能mysql 的索引掃瞄做排序章節,並且親身實踐了一下,發現有些結果與原書不一樣,個人猜測是mysql版本不一樣造成的,下面分享一下我個人的筆記。mysql 有兩種方式生成有序結果 通過排序操作或者按索引順序掃瞄。如果explain出來type列的值為index,則說明mysql使用索...
Mysql索引掃瞄排序
mysql有兩種操作可以用來生成有序結果 排序操作 將查詢出來的結果使用排序演算法進行排序 按索引順序掃瞄 order by語句後跟著乙個被索引的列,如此一來索引的順序就是索引對應記錄的順序,這樣直接順著索引一直往下讀取記錄即可得到有序的結果。按照索引順序掃瞄的好處是不言而喻的,因為查詢出來的結果就...