我有两个功能相同的查询。其中一个表现很好,另一个表现很差。我看不出性能差异从何而来。
查询1:
SELECT id FROM subsource_position WHERE id NOT IN (SELECT position_id FROM subsource)
这返回了以下计划:
QUERY PLAN ------------------------------------------------------------------------------- Seq Scan on subsource_position (cost=0.00..362486535.10 rows=128524 width=4) Filter: (NOT (SubPlan 1)) SubPlan 1 -> Materialize (cost=0.00..2566.50 rows=101500 width=4) -> Seq Scan on subsource (cost=0.00..1662.00 rows=101500 width=4)
查询2:
SELECT id FROM subsource_position EXCEPT SELECT position_id FROM subsource;
计划:
QUERY PLAN ------------------------------------------------------------------------------------------------- SetOp Except (cost=24760.35..25668.66 rows=95997 width=4) -> Sort (cost=24760.35..25214.50 rows=181663 width=4) Sort Key: "*SELECT* 1".id -> Append (cost=0.00..6406.26 rows=181663 width=4) -> Subquery Scan on "*SELECT* 1" (cost=0.00..4146.94 rows=95997 width=4) -> Seq Scan on subsource_position (cost=0.00..3186.97 rows=95997 width=4) -> Subquery Scan on "*SELECT* 2" (cost=0.00..2259.32 rows=85666 width=4) -> Seq Scan on subsource (cost=0.00..1402.66 rows=85666 width=4) (8 rows)
我感觉我丢失了一个查询中明显不好的东西,或者我错误地配置了PostgreSQL服务器。我本以为可以NOT IN很好地进行优化。是NOT IN始终存在性能问题,还是有它在这里不优化的理由?
NOT IN
附加数据:
=> select count(*) from subsource; count ------- 85158 (1 row) => select count(*) from subsource_position; count ------- 93261 (1 row)
编辑 :我现在修复了下面提到的AB!= BA问题。但是我所说的问题仍然存在:查询1仍然比查询2严重得多。我相信,这是由于两个表的行数相似。
编辑2 :我正在使用PostgresQL 9.0.4。我无法使用EXPLAIN ANALYZE,因为查询#1花费的时间太长。所有这些列都不是空的,因此不应有任何区别。
编辑3 :我在这两个列上都有一个索引。我尚未完成查询#1(约10分钟后放弃)。查询#2立即返回。
由于您正在使用默认配置运行,因此请尝试增加work_mem。子查询最有可能最终被后台处理到磁盘,因为您只允许1Mb的工作内存。尝试10或20mb。