我想重写以下子查询,因为它在较大的查询中反复使用。使用的DBMS是Postgres,该表具有以下结构table (id uuid, seq int, value int)
。
给出id( 到目前为止,我的幼稚(慢速)解决方案如下: 例如查询 返回 出于测试目的,我尝试对相关的id_value
)的值,查询将在“表”中查找所有记录,其中seq 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;
答案 0 :(得分:1)
您可能有太多冗余索引,这使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;
但是,我只是怀疑查询正在返回大量行,从而影响了性能。