默认情况下,mysql对group by col1,col2 字段进行排序,这与order by col1 col2类似,如果显式的堆一个包含相同列的order by 子句,实际上没有什么影响,如果查询group by 但是用户想要避免不必要的排序,则可以指定order by null.
优化分页查询
一般查询是,通过创建覆盖索引能够比较好的提高性能,一个常见的问题就是limit 1000,20 查询出1020行,但是返回的是1000到1020条数据,其他数据都进行抛弃了
1.使用主键回表查询原表的记录,下面我们发现直接查询是进行全表查询,而使用主键关联回表查询可以提高查询效率
mysql> explain select film_id, description from film order by title limit 50,5 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: film
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1000
Extra: Using filesort
1 row in set (0.00 sec)
mysql> explain select a.film_id,a.description from film a inner join (select film_id from film order by title limit 50,5) b on a.film_id=b.film_id \G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: <derived2>
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 55
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: PRIMARY
table: a
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 2
ref: b.film_id
rows: 1
Extra: NULL
*************************** 3. row ***************************
id: 2
select_type: DERIVED
table: film
type: index
possible_keys: NULL
key: idx_title
key_len: 767
ref: NULL
rows: 1000
Extra: Using index
3 rows in set (0.00 sec)
2.记录上一次的某个位置,用记录上一页的最后一行的字段,在使用limit n ,
mysql> explain select * from payment where rental_id<15640 order by rental_id desc limit 10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: payment
type: range
possible_keys: fk_payment_rental
key: fk_payment_rental
key_len: 5
ref: NULL
rows: 8043
Extra: Using index condition
1 row in set (0.00 sec)
使用排序rental_id 记录上一页的最后位置,在根据这个位置过滤且使用limit n,可以有效提高查询的效率,但是在rental_id有大量重复的情况下,这种优化会丢失数据。