需要有关查询性能的帮助

时间:2018-11-23 09:32:56

标签: mysql query-performance

今天我面临以下查询中的奇怪问题。当我运行此查询时,它需要很长时间。例如。如果我只在“ 2018-01-01 00:00:00”和“ 2018-10-31 23:59:59”之间放“ where w2.cdate”,或者仅放“ s2.status ='NEW'”,则它给出即时的结果,但是如果我将这两个条件放在一起,则需要时间。我的“日期”和“状态”列均已建立索引。我可能怎么找到这个原因呢?

select w2.id from status s2
  inner join order w2 on s2.warenkorb__id=w2.id 
    where  w2.cdate between '2018-01-01 00:00:00' and '2018-10-31 23:59:59' and  s2.status='NEW'

在所有条件下的纯素结果 Explain Result with all condition

用日期条件解释结果 enter image description here

3 个答案:

答案 0 :(得分:0)

EXPLAIN语句结果的不同中可以看出,使用所有条件的情况不能Using Index

您可以添加以下两个复合索引并进行测试:

  1. (warenkorb__id, status)status表上。
  2. (id, cdate)order表上。

ALTER TABLE查询如下:

ALTER TABLE status ADD INDEX(warenkorb__id, status);

ALTER TABLE order ADD INDEX(id, cdate);

答案 1 :(得分:0)

您的数据模型允许每个订单包含多个状态。因此,为了直接查询,我将从订单表中选择ID,然后在WHERE条款中查询状态:

select id
from `order`
where cdate >= date '2018-01-01'
  and cdate <  date '2018-11-01'
  and id in (select warenkorb__id from status where status = 'NEW');

(在其他DBMS中,可以使用INTERSECT来代替,但是MySQL没有此功能。)

现在考虑两种方法:

  1. DBMS首先选择状态以获取订单。
  2. DBMS首先选择订单并查询其状态。

对于案例1,您想要:

create index idx1 on status (status, warenkorb__id);

以及您应该已经拥有的order(id)的索引。甚至提供覆盖指数:

create index idx2 on `order` (id, cdate);

对于案例2,您想要:

create index idx3 on `order` (cdate, id);
create index idx4 on status (warenkorb__id, status);

创建这四个索引,查看执行计划,并删除DBMS不使用的索引。

答案 2 :(得分:0)

无论优化程序决定从哪个表开始,这些方法都应该工作良好:

w2:  INDEX(cdate, id)
s2:  INDEX(status, warenkorb__id)

列的指定顺序很重要。 (我认为Thorsten的额外索引对没有任何帮助。)

有关架构的问题:

  • idPRIMARY KEY的{​​{1}}吗? (请提供w2,这样就不需要其他问题了。)
  • 两个表是否为1:1关系? 通常不是一个好的设计。似乎SHOW CREATE TABLE可能在status中。