Performance 如何加快表格之间的差异?

Performance 如何加快表格之间的差异?,performance,postgresql,indexing,diff,Performance,Postgresql,Indexing,Diff,我正在postgresql中进行表之间的差异,这需要很长的时间,因为每个表约13GB。。。 我目前的查询是: SELECT * FROM tableA EXCEPT SELECT * FROM tableB; 及 当我在两个(未索引的)表上进行差异时,需要1:40小时(1小时40分钟)才能获得新的和删除的行,我需要运行两次查询,使总时间达到3:30小时 我对它运行了Postgresql解释查询,以查看它在做什么。它看起来像是对第一个表进行排序,然后对第二个表进行排序,然后对它们进行比较。这让我

我正在postgresql中进行表之间的差异,这需要很长的时间,因为每个表约13GB。。。 我目前的查询是:

SELECT * FROM tableA EXCEPT SELECT * FROM tableB;

当我在两个(未索引的)表上进行差异时,需要1:40小时(1小时40分钟)才能获得新的和删除的行,我需要运行两次查询,使总时间达到3:30小时

我对它运行了Postgresql解释查询,以查看它在做什么。它看起来像是对第一个表进行排序,然后对第二个表进行排序,然后对它们进行比较。这让我想到,如果我为表编制索引,它们将被预排序,而diff查询将更快

索引每个表需要45分钟。索引后,每个差异需要1:35小时。 为什么索引只减少了总差异时间的5分钟?我假设它将超过一半,因为在未索引的查询中,我将对每个表进行两次排序(我需要运行两次查询)

因为其中一个表不会有太大的变化,所以只需要索引一次,另一个表将每天更新。因此,索引方法的总运行时间是45分钟,加上2倍的1:35,总共3:55小时,几乎4小时

我在这里做错了什么,我不可能明白为什么有了索引,我的净差异时间会比没有索引时大

这与我的另一个问题略有关系:

编辑: 这是两个表的模式,除了表名之外,它们是相同的

CREATE TABLE bulk.blue
(
  "partA" text NOT NULL,
  "type" text NOT NULL,
  "partB" text NOT NULL
)
WITH (
  OIDS=FALSE
);

在上面的语句中,您没有使用索引

你可以这样做:

SELECT * FROM tableA a
  FULL OUTER JOIN tableB b ON a.someID = b.someID
然后可以使用相同的语句来显示哪些表缺少值

SELECT * FROM tableA a
  FULL OUTER JOIN tableB b ON a.someID = b.someID
  WHERE ISNULL(a.someID) OR ISNULL(b.someID)

这将为您提供表A或表B中缺少的行。指定的查询需要对表的每一列进行比较

例如,如果tableA和tableB各有五列,则查询必须将tableA.col1与tableB.col1、tableA.col2与tableB.col2进行比较。表A.col5至表B.col5

如果只有少数列唯一标识记录,而不是表中的所有列,则将表连接到唯一标识记录的特定列上,将提高性能

上述语句假定尚未创建主键。如果定义了主键来指示哪些列唯一标识记录,那么我相信EXCEPT语句会考虑到这一点。

  • 你申请了什么样的索引?索引仅在改善
    WHERE
    条件时有用。如果您正在执行
    select*
    ,那么您将捕获所有字段,而索引可能什么也不做,但会占用空间,并在后台为db引擎添加更多的处理,以便将查询与索引缓存进行比较

  • 您可以尝试选择唯一字段并为这些唯一字段创建索引,而不是选择*

  • 您还可以使用
    外部联接
    来显示两个表中在唯一字段上不匹配的结果
  • 你可能要考虑对你的表[/LI]进行聚类。
  • 你在运行什么版本的Postgres
  • 你最后一次吸尘是什么时候

除上述情况外,13GB相当大,因此您需要检查配置设置。除非您的系统内存不足,否则运行该操作不会花费数小时。

确认正在使用索引(它们可能不在此类泛型except语句中),但您没有针对指定列进行连接,因此缺少显式连接可能不会导致优化查询:

这将帮助您更清楚地查看解释分析:


另外,如果希望索引立即执行良好,请确保在创建索引后对表进行分析:}

someID可以是任何字段,但它应该被索引。我尝试使用您的示例,但在联接中有两个条件(我有3列,其中两列是唯一的,第三列不是唯一的。下面是实际的查询和错误:SELECT*From bulk。“redNet”r full outer join bulk。“blueNet”b on(r.partA=b.partA)和(r.partB=b.partB),其中ISNULL(r.type)或ISNULL(b.type);错误:列r.parta不存在我猜我犯了一个简单的错误,有什么想法吗?我发现了我的1个问题。“type”必须在引号中,并且没有isnull()postgresql函数,它必须是:(表达式为NULL)。它现在正在运行,我将计时并查看需要多长时间。报告
解释分析
将非常有帮助,并且在进行更改后进行比较分析时应该始终这样做。例如,它会显示在添加索引后您仍然没有使用索引。顺便说一句,在索引上进行聚类将使使用正确的查询后,工作速度会大大加快。共有三列,所有三列都被索引。如果所有列都被索引,您是说“Select*”不使用索引,而“Select col1、col2、col3”将使用索引?您必须确定地查看查询计划,但是的,这正是我所说的,但Postgres是一个高级数据库,因此如果它确实查找这三列,我不会感到惊讶。将查询计划输出转储到中会更有帮助,感谢第二个链接,它非常有用。
SELECT * FROM tableA a
  FULL OUTER JOIN tableB b ON a.someID = b.someID
  WHERE ISNULL(a.someID) OR ISNULL(b.someID)