IN huge yang besar daftar sangat tidak efisien. PostgreSQL idealnya harus mengidentifikasinya dan mengubahnya menjadi relasi yang anti-gabung, tetapi pada titik ini perencana kueri tidak tahu bagaimana melakukannya, dan waktu perencanaan yang diperlukan untuk mengidentifikasi kasus ini akan menghabiskan biaya setiap kueri yang menggunakan NOT IN masuk akal, jadi itu harus menjadi cek biaya yang sangat rendah. Lihat jawaban yang jauh lebih mendetail sebelumnya tentang topik ini
.
Seperti yang ditulis David Aldridge, ini paling baik diselesaikan dengan mengubahnya menjadi anti-gabung. Saya akan menulisnya sebagai gabungan di atas VALUES daftar hanya karena PostgreSQL sangat cepat dalam menguraikan VALUES daftar ke dalam relasi, tetapi efeknya sama:
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;
Untuk kumpulan nilai yang cukup besar, Anda mungkin lebih baik membuat tabel sementara, COPY memasukkan nilai ke dalamnya, membuat PRIMARY KEY di atasnya, dan bergabung dengan itu.
Lebih banyak kemungkinan dieksplorasi di sini:
https://stackoverflow.com/a/17038097/398670