这个SQL查询可以提高效率吗?

时间:2012-06-26 13:14:33

标签: sql postgresql

我有一个非常大的节点表(基数大约为600,000),此表中的每条记录都可以有一个或多个与之关联的类型。有一个 node_types 表包含这些(30个左右)类型定义。

要连接这两个,我有一个名为 node_type_relations 的第三个表,它只是将节点ID链接到类型ID。

我试图在剔除节点表后清理孤立的node_type_relation条目。我删除节点不再存在的任何类型关系的查询是

DELETE FROM node_type_relations WHERE node_id NOT IN (SELECT id FROM nodes)

但是从运行速度判断(每10秒左右删除一条记录),看起来Postgres正在为node_type_relations表中的每条记录加载整个节点表一次(大约140万记录大小)。

我正准备潜入并编写一些代码来更明智地做这件事,当我以为我会问这里查询是否可以以某种方式从内到外翻转。任何避免多次加载节点表的事情。

一如既往地谢谢。


使用解决方案进行编辑

执行查询;

DELETE FROM node_type_relations WHERE NOT EXISTS (SELECT 1 FROM nodes WHERE nodes.id=node_type_relations.node_id)

似乎已经产生了预期的效果,并在几秒钟内删除了所有孤立的记录(大约170,000个)。

2 个答案:

答案 0 :(得分:3)

也许做左连接,然后删除null。

所以:

 DELETE ntr
 FROM node_type_relations ntr
 LEFT JOIN nodes n
 ON n.id = ntr.node_id
 WHERE n.id IS NULL

答案 1 :(得分:1)

@lynks'找到了他自己案例的最佳查询 - 使用EXISTS半连接:

DELETE FROM node_type_relations ntr
WHERE  NOT EXISTS (
   SELECT 1
   FROM   nodes n
   WHERE  n.id = ntr.node_id
   );

使用JOIN语法的解决方案必须在PostgreSQL中构造如下:

DELETE FROM node_type_relations d
USING  node_type_relations ntr
LEFT   JOIN nodes n ON n.id = ntr.node_id
WHERE  ntr.node_id = d.node_id
AND    n.id IS NULL;