当前位置: 首页 > 面试题库 >

PostgreSQL:NOT IN与EXCEPT的性能差异(编辑#2)

澹台冯浩
2023-03-14
问题内容

我有两个功能相同的查询。其中一个表现很好,另一个表现很差。我看不出性能差异从何而来。

查询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始终存在性能问题,还是有它在这里不优化的理由?

附加数据:

=> 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。



 类似资料:
  • 这不是重复我的问题,我查了一下,更多的是关于内部匿名类。 我对Lambda表达式很好奇,并测试了以下内容: 如果给定一个数组中有1000个索引,那么对于一个包含1000个索引的循环,删除哪个条目会更快 最初的结果并不令人惊讶,因为我不知道自己会想出什么: 但后来,我决定将常量改为一百万,结果如下: 为了让阅读更简单,以下是结果: 我有以下问题: > 这背后的魔力是什么?当要使用的索引是*100时,

  • 上次,我发现了Java8及以上版本函数式编程的难点,并在Collectors类中发现了一个静态方法。 我们有一个类员工像: 假设我们有一个类的POJO列表,并且我们希望接收一个所有员工姓名的列表。我们有两种方法,比如: 我知道第一种方法在上使用终端操作,而第二种方法在上使用中间操作,但我想知道第一种方法的性能是否比第二种方法差,反之亦然。如果您能解释第一种情况的潜在性能下降,当我们的数据源(emp

  • a.它是如何工作的? b。它是否保存?比较两棵树是不是很贵? React不直接操作部件。 A.指的是什么?

  • 问题内容: 一个非常简单的问题,但这是来自C / C ++人员进入Java的复杂性的。 我知道我可以启动jUnit和自己的一些性能测试来获得答案。但我只是想知道这是否在那里。 在性能方面,String.replaceAll()和Matcher.replaceAll()(在从Regex.Pattern创建的Matcher对象上)之间是否存在已知差异? 此外,两者在高级API方面的区别是什么?(不可变

  • 问题内容: 我试图坚持保持数据库规范化的做法,但这导致需要运行多个联接查询。如果许多查询使用联接而不是调用可能包含冗余数据的单个表,性能是否会下降? 问题答案: 直到发现瓶颈后,数据库才能正常化。然后,只有在仔细分析后,您才能对它们进行反规范化。 在大多数情况下,拥有一套覆盖面广的索引和最新的统计信息将可以解决大多数性能和阻塞问题,而不会进行任何非规范化。 如果对表进行写入和读取操作,则使用单个表

  • 问题内容: 我正在运行以下代码,但有时在运行时会出现某种并发异常。 我对其进行了重构以解决并发问题,但这确实使我提出了一个问题。如果将for构造更改为Iterator模式,性能会有所不同吗?foreach构造和Iterator类之间的访问级别有什么区别? 问题答案: 区别主要在于语法糖,不同之处在于可以从迭代中删除项目。从技术上讲,增强的循环使您可以循环遍历所有,其中至少包括s和数组。 不必担心性