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

橙子

我想重写以下子查询,因为它在较大的查询中反复使用。使用的DBMS是Postgres,该表具有以下结构table (id uuid, seq int, value int)

给定id(id_value的值,查询将在“表”中查找seq <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;

在此处输入图片说明

戈登·利诺夫

您可能有太多的冗余索引,使Postgres感到困惑。简单地定义一个列primary keyunique就足够了。您不需要多个索引声明。

对于您想做的事情,这应该是最佳的:

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;

但是,我只是怀疑查询正在返回大量的行,从而影响了性能。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章