sql—消除子查询以提高查询性能

vjhs03f7  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(285)

我想重写下面的子查询,因为它在更大的查询中反复使用。使用的数据库管理系统是postgres,表的结构如下 table (id uuid, seq int, value int) .
给定id的值( id_value ),查询将查找“table”中的所有记录,其中seq<seq of id\u 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

e、 g.查询

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;

qhhrdooz

qhhrdooz1#

你可能有这么多多余的索引,你是混淆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;

然而,我的怀疑仅仅是查询返回了大量的行,这影响了性能。

相关问题