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