巨大な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