mysql性能优化学习笔记(3)常见sql语句优化


一、max()优化
mysql> explain select max(payment_date) from payment;
+----+-------------+---------+------+---------------+------+---------+------+-------+-------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows  | Extra |
+----+-------------+---------+------+---------------+------+---------+------+-------+-------+
|  1 | SIMPLE      | payment | ALL  | NULL          | NULL | NULL    | NULL | 14394 |       |
+----+-------------+---------+------+---------------+------+---------+------+-------+-------+
1 row in set (0.00 sec)

mysql> create index idx_paymentdate on  payment(payment_date);
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain select max(payment_date) from payment;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.00 sec)

从返回行数上来说,效率比较高。

二、count()的优化

分别查询出2005年和2006年影片产量

mysql> select count(release_year=2006 or null) as 'film2006',count(release_year=2005 or null) as 'film2005' from film;
+----------+----------+
| film2006 | film2005 |
+----------+----------+
|     1000 |        0 |
+----------+----------+
1 row in set (0.00 sec)


三、子查询方式
通常情况下,需要把子查询优化成join查询,但是在优化中需要注意关联键是否存在一对多关系,要注意重复数据(distinct)

四、group by 查询方式
group by可能会出现临时表(Using temporary),文件排序(Using filesort)等,影响效率。
可以通过关联的子查询,来避免产生临时表和文件排序,可以节省io
改写前
select actor.first_name,actor.last_name,count(*)
from sakila.film_actor
inner join sakila.actor using(actor_id)
group by film_actor.actor_id;
改写后
select actor.first_name,actor.last_name,c.cnt
from sakila.actor inner join(
select actor_id,count(*) as cnt from sakila.film_actor group by
actor_id
)as c using(actor_id);

五、limit查询
limit常用于分页处理,时常会伴随order by从句使用,因此大多时候会使用Filesorts这样会造成大量的io问题
1.使用有索引的列或主键进行order by操作
2.记录上次返回的主键,在下次查询时使用主键过滤
使用这种方式有一个限制,就是主键一定要顺序排序和连续的,如果主键出现空缺可能会导致最终页面上显示的列表不足5条,解决办法是附加一列,保证这一列是自增的并增加索引就可以了


posted @ 2015-11-22 19:49  GeorgeHao  阅读(239)  评论(0编辑  收藏  举报