问题描述
|
我正在做postgresql中的表之间的差异,这需要很长时间,因为每个表约为13GB ...
我当前的查询是:
SELECT * FROM tableA EXCEPT SELECT * FROM tableB;
和
SELECT * FROM tableB EXCEPT SELECT * FROM tableA;
当我对两个(未索引)表进行比较时,它需要1:40小时(1小时40分钟)才能获取新行和已删除行,因此我需要运行两次查询,使总时间达到3: 30小时。
我在上面运行了Postgresql EXPLAIN查询,以查看它在做什么。看起来它正在对第一个表进行排序,然后对第二个表进行排序,然后对其进行比较。好吧,这让我想到,如果我为表建立索引,它们将被预先排序,并且diff查询会更快。
索引每个表花费了45分钟。编制索引后,每个Diff花费了1:35个小时。
为什么索引仅将总比较时间减少了5分钟?我会假设它将超过一半,因为在未索引的查询中,我对每个表进行了两次排序(我需要运行两次查询)
由于这些表中的一个不会有太大变化,因此只需要索引一次,其他表将每天进行更新。因此,索引方法的总运行时间是索引的45分钟,加上diff的2x 1:35,总共3:55小时,几乎是4小时。
我在这里做错了什么,我看不到为什么使用索引时我的网络差异时间比没有索引时大?
这在这里稍微参考了我的另一个问题:Postgresql UNION花费的时间是运行单个查询的时间的10倍
编辑:
这是两个表的架构,除了表名外,它们是相同的。
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中缺少的行
, 确认您正在使用索引(它们可能不在此类通用的except语句中),但是您没有针对指定的列进行联接,因此很可能缺乏显式联接将无法优化查询:
http://www.postgresql.org/docs/9.0/static/indexes-examine.html
这将帮助您更清楚地查看解释分析:
http://explain.depesz.com
另外,如果要立即创建索引,请确保在创建索引后对表进行分析:}
, 指定的查询需要对表的每一列进行比较。
例如,如果tableA和tableB分别具有五列,则查询必须将tableA.col1与tableB.col1,tableA.col2与tableB.col2,...进行比较。 。 。 tableA.col5至tableB.col5
如果只有少数几列可以唯一地标识一条记录,而不是表中的所有columnS,那么将表与特定列上的唯一标识一条记录连接起来将提高性能。
上面的语句假定尚未创建主键。如果已经定义了一个主键来指示哪些列可以唯一地标识一条记录,那么我相信EXCEPT语句将考虑到这一点。
,
您使用哪种指数?索引仅对改善“ 5”度条件有用。如果您执行的是select *
,则说明您正在抓取所有字段,索引可能没有执行任何操作,而是占用了空间,并在后台增加了一些处理,以便db引擎将查询与索引缓存。
您可以尝试选择唯一字段并为这些唯一字段创建索引,而不是“ 7”
您也可以使用OUTER JOIN
来显示两个表中唯一字段都不匹配的结果
您可能要考虑将表群集
您正在运行哪个版本的Postgres?
您上次打扫的时间是什么时候?
除了上述以外,13GB还很大,因此您需要检查配置设置。除非您的系统上没有足够的内存,否则运行该程序无需花费数小时。