[英]Eliminate subquery to improve query performance
我想重写以下子查询,因为它在更大的查询中一遍又一遍地使用。 使用的 DBMS 是 Postgres,该表具有以下结构table (id uuid, seq int, value int)
。
给定 id ( id_value
) 的值,查询在“表”中查找所有记录,其中 seq < seq of id_value
到目前为止,我的幼稚(缓慢)解决方案如下:
select * from table
where seq < (select seq from table where id = id_value)
table
id, seq, value
a, 1, 12
b, 2, 22
c, 3, 32
x, 4, 43
d, 5, 54
s, 6, 32
a, 7, 54
例如查询
select * from table where seq < (select seq from table where id = 'x')
返回
a, 1, 12
b, 2, 22
c, 3, 32
出于测试目的,我尝试对相关的seq
字段进行硬编码,它显着改进了整个查询,但我真的不喜欢将seq
查询为一个两阶段的过程。 理想情况下,这可能作为查询的一部分发生。 任何想法或灵感将不胜感激。
CREATE TABLE foo
(
seq integer NOT NULL,
id uuid NOT NULL,
CONSTRAINT foo_pkey PRIMARY KEY (id),
CONSTRAINT foo_id_key UNIQUE (id),
CONSTRAINT foo_seq_key UNIQUE (seq)
);
CREATE UNIQUE INDEX idx_foo_id
ON public.foo USING btree
(id)
TABLESPACE pg_default;
CREATE UNIQUE INDEX idx_foo_seq
ON public.foo USING btree
(seq)
TABLESPACE pg_default;
您可能有太多冗余索引,以至于您对 Postgres 感到困惑。 只需将列定义primary key
或unique
的就足够了。 您不需要多个索引声明。
对于您想要做的事情,这应该是最佳的:
select f.*
from foo f
where f.seq < (select f2.seq from foo f2 where f2.id = :id_value)
这应该使用索引来获取子查询中的seq
值。 然后它应该返回适当的行。
你也可以试试:
select f.*
from (select f.*, min(seq) filter (where id = :id_value) over () as min_seq
from foo f
) f
where seq < min_seq;
但是,我的怀疑只是查询返回了大量行,这会影响性能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.