巨大なIN
リストは非常に非効率的です。 PostgreSQLは理想的にはそれを識別し、それを反結合を行う関係に変換する必要がありますが、この時点でクエリプランナーはそれを行う方法を知らず、このケースを識別するために必要な計画時間は、すべてのクエリにコストがかかります。 NOT IN
を使用します 賢明なことに、それは非常に低コストのチェックでなければならないでしょう。 このトピックに関する以前のはるかに詳細な回答
を参照してください。 。
デビッドオルドリッジが書いたように、これは反結合に変えることによって最もよく解決されます。 VALUES
の結合として記述します PostgreSQLがVALUES
の解析に非常に高速であるという理由だけでリストします 関係にリストしますが、効果は同じです:
SELECT entityid
FROM entity e
LEFT JOIN level1entity l1 ON l.level1id = e.level1_level1id
LEFT JOIN level2entity l2 ON l2.level2id = l1.level2_level2id
LEFT OUTER JOIN (
VALUES
(1377776),(1377792),(1377793),(1377794),(1377795),(1377796)
) ex(ex_entityid) ON (entityid = ex_entityid)
WHERE l2.userid = 'a987c246-65e5-48f6-9d2d-a7bcb6284c8f'
AND ex_entityid IS NULL;
値のセットが十分に大きい場合は、一時テーブルCOPY
を作成する方がよい場合があります。 値を入力して、PRIMARY KEY
を作成します その上で、それに参加します。
ここで探求されるその他の可能性:
https://stackoverflow.com/a/17038097/398670