1

ノードの非常に大きなテーブル(カーディナリティが約 600,000) があります。このテーブルの各レコードには、関連付けられた 1 つ以上のタイプを含めることができます。これら (30 程度) の型定義を含むnode_typesテーブルがあります。

この 2 つを接続するために、node_type_relationsという 3 番目のテーブルを作成します。このテーブルは、ノード ID をタイプ ID に単純にリンクします。

ノード テーブルのカリング後に、孤立した node_type_relation エントリをクリーンアップしようとしています。ノードが存在しなくなったタイプの関係を削除する私のクエリは次のとおりです。

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

しかし、これが実行される速度 (10 秒ごとに 1 つのレコードが削除される程度) から判断すると、Postgres は node_type_relations テーブル内のレコードごとに 1 回ノード テーブル全体をロードしているように見えます (サイズは約 140 万レコードです)。 )。

私は飛び込んで、より賢明にそれを行うためのコードを書こうとしていましたが、クエリを何らかの方法で裏返しにすることができるかどうかここで尋ねようと思いました。ノードテーブルを複数回ロードすることを避けるためのもの。

いつもありがとう。


ソリューションで編集

クエリを実行します。

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

望ましい効果があり、孤立したすべてのレコード (約 170,000) を数秒で削除したようです。

4

2 に答える 2

3

おそらく、左結合を実行してから、null の場所を削除します。

そう:

 DELETE ntr
 FROM node_type_relations ntr
 LEFT JOIN nodes n
 ON n.id = ntr.node_id
 WHERE n.id IS NULL
于 2012-06-26T13:19:55.633 に答える
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;
于 2012-06-26T19:46:15.677 に答える