zoukankan      html  css  js  c++  java
  • 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条,解决办法是附加一列,保证这一列是自增的并增加索引就可以了


  • 相关阅读:
    BZOJ 2034 【2009国家集训队】 最大收益
    vijos P1780 【NOIP2012】 开车旅行
    BZOJ 2115 【WC2011】 Xor
    BZOJ 3631 【JLOI2014】 松鼠的新家
    BZOJ 4717 改装
    BZOJ 2957 楼房重建
    BZOJ 4034 【HAOI2015】 T2
    BZOJ 1834 【ZJOI2010】 network 网络扩容
    BZOJ 2440 【中山市选2011】 完全平方数
    BZOJ 2733 【HNOI2012】 永无乡
  • 原文地址:https://www.cnblogs.com/haodaquan/p/4986570.html
Copyright © 2011-2022 走看看