前言:
mysql有兩種方式可以生成有序的結果:通過排序操作或者按索引順序掃瞄,如果explain出來的type列的值為index,則說明mysql使用了索引掃瞄來做排序。
掃瞄索引本身是很快的,因為只需要從一條索引記錄移動到緊接著的下一條記錄。但如果索引不能覆蓋查詢所需的全部列,那麼就不得不每掃瞄一條索引記錄就得回表查詢一次對應的行,這基本都是隨機io,因此按索引順序讀取資料的速度通常要比順序地全表掃瞄慢。
mysql可以使用同乙個索引即滿足排序,又用於查詢行,如果可能的話,設計索引時應該盡可能地同時滿足這兩種任務。
只有當索引的列順序和order by子句的順序完全一致,並且所有列的排序方式都一樣時,mysql才能夠使用索引來對結果進行排序,如果查詢需要關聯多張表,則只有當order by子句引用的字段全部為第一張表時,才能使用索引做排序。order by子句和查詢型查詢的限制是一樣的,需要滿足索引的最左字首的要求,否則,mysql都需要執行順序操作,而無法利用索引排序。
# 使用索引掃瞄來做排序
mysql有兩種方式可以生成有序的結果:通過排序操作或者按索引順序掃瞄,如果explain出來的type列的值為index,則說明mysql使用了索引掃瞄來做排序
掃瞄索引本身是很快的,因為只需要從一條索引記錄移動到緊接著的下一條記錄。但如果索引不能覆蓋查詢所需的全部列,那麼就不得不每掃瞄一條索引記錄就得回表查詢一次對應的行,這基本都是隨機io,因此按索引順序讀取資料的速度通常要比順序地全表掃瞄慢
mysql可以使用同乙個索引即滿足排序,又用於查詢行,如果可能的話,設計索引時應該盡可能地同時滿足這兩種任務。
只有當索引的列順序和order by子句的順序完全一致,並且所有列的排序方式都一樣時,mysql才能夠使用索引來對結果進行排序,如果查詢需要關聯多張表,則只有當orderby子句引用的字段全部為第一張表時,才能使用索引做排序。order by子句和查詢型查詢的限制是一樣的,需要滿足索引的最左字首的要求,否則,mysql都需要執行順序操作,而無法利用索引排序
sql--注意,這是mysql5.7執行的結果,mysql8執行有些地方會不同,理解下意思就行,資料庫是mysql官網上的sakila
sakila資料庫中rental表在rental_date,inventory_id,customer_id上有rental_date的索引(rental_date為組合索引,包括rental_date,inventory_id,customer_id)
1、使用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
1 row in set, 1 warning (0.00 sec)
order by子句不滿足索引的最左字首的要求,也可以用於查詢排序,這是因為所以你的第一列(rental_date='2005-05-25')被指定為乙個常數
2、該查詢為索引的第一列提供了常量條件,而使用第二列進行排序,將兩個列組合在一起,就形成了索引的最左字首
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
1 row in set, 1 warning (0.00 sec)
3、下面的查詢不會利用索引(第一列使用了範圍查詢)
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
4、該查詢使用了兩中不同的排序方向,但是索引列都是正序排序的
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
1 row in set, 1 warning (0.00 sec)
5、該查詢中引用了乙個不再索引中的列
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
1 row in set, 1 warning (0.00 sec)
使用索引掃瞄來做排序 mysql索引優化
mysql有兩種方式可以生成有序的結果 通過排序操作或者按索引順序掃瞄,如果explain出來的type列的值為index,則說明mysql使用了索引掃瞄來做排序 掃瞄索引本身是很快的,因為只需要從一條索引記錄移動到緊接著的下一條記錄。但如果索引不能覆蓋查詢所需的全部列,那麼就不得不每掃瞄一條索引記...
Mysql索引掃瞄排序
mysql有兩種操作可以用來生成有序結果 排序操作 將查詢出來的結果使用排序演算法進行排序 按索引順序掃瞄 order by語句後跟著乙個被索引的列,如此一來索引的順序就是索引對應記錄的順序,這樣直接順著索引一直往下讀取記錄即可得到有序的結果。按照索引順序掃瞄的好處是不言而喻的,因為查詢出來的結果就...
mysql索引 之使用索引掃瞄做排序
今天看了 高效能mysql 的索引掃瞄做排序章節,並且親身實踐了一下,發現有些結果與原書不一樣,個人猜測是mysql版本不一樣造成的,下面分享一下我個人的筆記。mysql 有兩種方式生成有序結果 通過排序操作或者按索引順序掃瞄。如果explain出來type列的值為index,則說明mysql使用索...