postgresql查询计划奇怪的行为

时间:2017-02-14 19:33:48

标签: performance postgresql indexing sql-execution-plan

我必须根据column_X(table_B在该列上有一个索引,btree)选择一个表中的行(table_A相当小< 10K行),这些行在另一个表中没有对应的行(table_B超过500K行)。 如果我使用以下查询:

select a.column1,
    a.column2,
    a.column3,
    a.column_X,
    b.column_X
from table_A a
left outer join table_B b on a.column_X = b.column_X
where a.column_X <> 0
    and b.column_X is null

查询(168个结果行)在大约600ms内执行。 另一方面,如果我尝试不同的查询:

select column1,
    column2,
    column3,
    column_X
from table_A
where column_X not in (
        select column_X
        from table_B
        where column_X is not null
        )
    and column_X <> 0

检索相同的168行大约需要8分钟。 column_X的类型为bigint,并且转换似乎没有区别(在第二个查询中,索引从未使用过)。 有什么想法吗?

1 个答案:

答案 0 :(得分:1)

NOT IN子选择优于其他任何子选项。由于不同的语义PostgreSQL不能使用反连接。如果可以,请不要使用此模式。请改为使用NOT EXISTS或外部联接。