可以优化时间属性查询以删除MAX子查询吗?

时间:2019-05-15 17:43:13

标签: mysql sql

我有以下DDL正在尝试实现Temporal Property pattern

CREATE TABLE IF NOT EXISTS `docs` (
  `id` int(6) NOT NULL,
  `effective_on` DATE NOT NULL,
  `name` varchar(200) NOT NULL,
  `value` varchar(200) NOT NULL,
  `superceded_by` int(6),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

create unique index zzz on `docs` (id);
alter table `docs` add FOREIGN KEY (superceded_by) REFERENCES docs(id) ON DELETE CASCADE;

CREATE UNIQUE INDEX xyz ON `docs` (name, effective_on, superceded_by);

和相应的查询

select `value` from docs
where
superceded_by is null and name = 'p1' and
effective_on = (
select max(effective_on) from docs
where
superceded_by is null
and effective_on <= '2017-01-01'
and name = 'p1' )

http://sqlfiddle.com/#!9/a07c84/1

当前的SQL使用了一个子查询,我想知道它是否可以消除或进一步简化查询的性能。

2 个答案:

答案 0 :(得分:0)

为了提高性能,您应该在

上添加一个复合索引
table docs  columns (effective_on, name, superceded_by ) 

您对id的唯一索引不满意,您已经对id有了主键索引

以及表本身对外键的约束都没有意义

答案 1 :(得分:0)

我会这样写查询:

select d.`value`
from docs d
where d.superceded_by is null and
      d.name = 'p1' and
      d.effective_on = (select max(d2.effective_on)
                        from docs d2
                        where d2.superceded_by is null and
                              d2.name = d.name and
                              d2.effective_on <= '2017-01-01'
                       );

然后,您要在docs(name, superceded_by, effective_on)上建立索引。索引中列的顺序非常重要。第一个键用于相关子句;第二个用于通过superceded_by进行过滤。然后应扫描最终密钥以获取正确的日期。