需要查询性能方面的帮助吗

uttx8gqw  于 2021-06-17  发布在  Mysql
关注(0)|答案(3)|浏览(278)

今天我面临一个奇怪的问题,我有以下疑问。当我运行这个查询时,需要很长时间。e、 如果我只写“where”  w2.cdate介于“2018-01-01 00:00:00”和“2018-10-31 23:59:59”之间,或者仅为“s2.status='new'”,则会立即给出结果,但如果将这两个条件放在一起,则需要时间。我的“cdate”和“status”列都被编入索引。这背后有什么原因?我怎么能找到呢。

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'

所有条件下的打印结果

用日期条件解释结果

sauutmhj

sauutmhj1#

您的数据模型允许每个订单有多个状态。因此,为了直接得到查询,我将从order表中选择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没有这个特性。)
现在考虑两种方法:
dbms首先选择状态以获取订单。
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不使用的索引。

of1yzvn4

of1yzvn42#

正如你可以看到的不同 EXPLAIN 陈述结果,说明本案使用的所有条件都不能成立 Using Index .
您可以添加以下两个复合索引并进行测试: (warenkorb__id, status)status table。 (id, cdate)order table。 ALTER TABLE 查询如下:

ALTER TABLE status ADD INDEX(warenkorb__id, status);

ALTER TABLE order ADD INDEX(id, cdate);
uz75evzq

uz75evzq3#

无论优化器决定从哪个表开始,这些都应该很好地工作:

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

列的指定顺序很重要(我不认为托尔斯滕额外的一对索引有任何帮助。)
关于模式的问题:
id 这个 PRIMARY KEYw2 ? (请提供 SHOW CREATE TABLE 所以不需要这个问题和其他问题。)
这两张table的比例是1:1吗?那通常不是一个好的设计。看来 status 可能在里面 w2 .

相关问题