今天我面临以下查询中的奇怪问题。当我运行此查询时,它需要很长时间。例如。如果我只在“ 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'
答案 0 :(得分:0)
从EXPLAIN
语句结果的不同中可以看出,使用所有条件的情况不能Using Index
。
您可以添加以下两个复合索引并进行测试:
(warenkorb__id, status)
在status
表上。(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,您想要:
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的额外索引对没有任何帮助。)
有关架构的问题:
id
是PRIMARY KEY
的{{1}}吗? (请提供w2
,这样就不需要其他问题了。)SHOW CREATE TABLE
可能在status
中。