如何改进这个复杂的查询?

时间:2015-04-21 07:37:29

标签: mysql performance innodb

我的查询运行时间很长。我尝试通过在website_id表中的hh_hits添加索引来提高查询性能。

查询:

SELECT

    w.state, xx.pretty_name, xx.member_id,
    SUM(ce.total_charge) as total_charge,
    SUM(ce.shipping_cost) as shipping_cost,
    SUM(ce.product_price * product_count) as product_price,
    SUM(ce.tax) as tax,
    SUM(ce.service_charge) as service_charge,
    COUNT(distinct ce.order_id) as order_count,
    SUM(ce.product_count) as product_count,
    SUM( (select sum(addon_price*addon_count)
             from wow.cart_entry_addons_archive cean
              where cean.cart_entry_id=ce.cart_entry_id
                and cean.addon_type='xx'
              group by ce.cart_entry_id)) as giftwrap_total,
    sum( (select sum(addon_price*addon_count)
              from wow.cart_entry_addons_archive cean2
              where cean2.cart_entry_id=ce.cart_entry_id
                and cean2.addon_type='xx'
              group by ce.cart_entry_id)) as addon_total,
    (select sum(number) as hits
              from wow.hh_hits thts
              where thts.website_id=xx.website_id
                and thts.start_date >= 'xxx'
                and thts.start_date <= 'xx') as visits

FROM

    wow.carts_archive c,
    wow.cart_entries_archive ce,
    eoe.websites xx

WHERE

    ce.order_date >= 'xx' and
    ce.order_date <= 'xx' and
    ce.website_id=xx.website_id and
    lower(ce.status) != 'deleted' and
    ce.order_status != 'cancelled' and
    ce.cart_id = c.cart_id and
    (c.cc_number <> '343334' or c.cc_number is null)
GROUP BY ce.website_id
ORDER BY ce.website_id;

解释计划:

+----+--------------------+-------+--------+------------------+----------+---------+---------------------------+-------+----------------------------------------------+
| id | select_type        | table | type   | possible_keys    | key      | key_len | ref                       | rows  | Extra                                        |
+----+--------------------+-------+--------+------------------+----------+---------+---------------------------+-------+----------------------------------------------+
|  1 | PRIMARY            | ce    | range  | id1_nn,idx_726   | idx_1049 | 9       | NULL                      |    33 | Using where; Using filesort                  |
|  1 | PRIMARY            | w     | ref    | idx_1055         | idx_1055 | 5       | wow.ce.website_id         |     1 | Using where                                  |
|  1 | PRIMARY            | c     | eq_ref | PRIMARY          | PRIMARY  | 4       | eoe.ce.cart_id            |     1 | Using where                                  |
|  4 | DEPENDENT SUBQUERY | thts  | ALL    | hh_n1            | NULL     | NULL    | NULL                      | 24493 | Using where                                  |
|  3 | DEPENDENT SUBQUERY | cean2 | ref    | idx_1383         | idx_1383 | 4       | wow.ce.cart_entry_id      |     1 | Using where; Using temporary; Using filesort |
|  2 | DEPENDENT SUBQUERY | cean  | ref    | idx_1383         | idx_1383 | 4       | wow.ce.cart_entry_id      |     1 | Using where; Using temporary; Using filesort |

查询解释计划似乎hh_hits表没有使用索引。

1 个答案:

答案 0 :(得分:0)

在hh_hits上,添加此复合索引:

INDEX(website_id, start_date)

如需进一步讨论,请为每个表格提供SHOW CREATE TABLE

如果我的建议不够,那么我们应该讨论构建一个包含每个网站日期对的小计的汇总表。你会每晚扩充表格,然后针对它运行相关的子查询。