【问题标题】:How to improve this complex query?如何改进这个复杂的查询?
【发布时间】:2015-04-21 07:37:28
【问题描述】:

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

查询:

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 表没有使用索引。

【问题讨论】:

  • 你的数据库引擎是什么? mysql还是sql?
  • Mysql 和 db 引擎是 innodb。
  • @Lucky:通常这类问题会被标记为两者(因为 MySQL SQL 也是 SQL)。但是,sql 标记要求它仅用于 ANSI SQL 问题,因此您的编辑是正确的。

标签: mysql performance innodb


【解决方案1】:

在 hh_hits 上,添加这个复合索引:

INDEX(website_id, start_date)

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

如果我的建议没有足够的帮助,那么我们应该讨论构建一个汇总表,其中包含每个网站-日期对的小计。您将每晚扩充该表,然后针对它运行相关子查询。

【讨论】:

    猜你喜欢
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    相关资源
    最近更新 更多