Di Postgres, Anda dapat menentukan klausa IN, seperti ini:
SELECT * FROM user WHERE id IN (1000, 1001, 1002)
Adakah yang tahu berapa jumlah maksimum parameter yang dapat Anda berikan ke IN?
postgresql
Alex Riley
sumber
sumber
RENCANA QUERY
Tetapi jika coba kueri ke-2:
RENCANA QUERY
Kita dapat melihat bahwa postgres membuat tabel temp dan bergabung dengannya
sumber
Tidak ada batasan jumlah elemen yang Anda lewati untuk klausa IN. Jika ada lebih banyak elemen, ia akan menganggapnya sebagai array dan kemudian untuk setiap pemindaian dalam database, ia akan memeriksa apakah terdapat dalam array atau tidak. Pendekatan ini tidak begitu scalable. Alih-alih menggunakan klausa IN coba gunakan INNER JOIN dengan temp table. Lihat http://www.xaprb.com/blog/2006/06/28/why-large-in-clauses-are-problematic/ untuk info lebih lanjut. Menggunakan skala INNER JOIN serta pengoptimal kueri dapat menggunakan hash join dan optimisasi lainnya. Sedangkan dengan klausa IN tidak ada cara bagi pengoptimal untuk mengoptimalkan kueri. Saya perhatikan speedup minimal 2x dengan perubahan ini.
sumber
OR
danIN
klausa karena besarnya overhead dalam penguraian dan perencanaan kueri seperti itu, saya tidak dapat mengkonfirmasi masalah dengan Postgres 9.5, lihat jawaban ini .Sebagai seseorang yang lebih berpengalaman dengan Oracle DB, saya juga khawatir tentang batasan ini. Saya melakukan tes kinerja untuk kueri dengan ~ 10'000 parameter dalam daftar
IN
, mengambil bilangan prima hingga 100'000 dari tabel dengan bilangan bulat 100'000 pertama dengan benar-benar mendaftarkan semua bilangan prima sebagai parameter kueri .Hasil saya menunjukkan bahwa Anda tidak perlu khawatir tentang kelebihan pengoptimal rencana kueri atau mendapatkan rencana tanpa penggunaan indeks , karena itu akan mengubah kueri untuk digunakan di
= ANY({...}::integer[])
mana ia dapat meningkatkan indeks seperti yang diharapkan:Namun, utas ini (yang agak lama) pada milis pgsql-hacker menunjukkan bahwa masih ada biaya yang tidak dapat diabaikan dalam perencanaan pertanyaan semacam itu, jadi terima kata-kata saya dengan sebutir garam.
sumber
Jika Anda memiliki pertanyaan seperti:
Anda dapat meningkatkan kinerja jika menulis ulang kueri Anda seperti:
sumber
EXPLAIN
mengatakan secara internal menulis ulangIN (...)
as sayaANY ('{...}'::integer[])
.Baru saja mencobanya. jawabannya adalah -> integer out-of-range sebagai nilai 2-byte: 32768
sumber
Anda mungkin ingin mempertimbangkan refactoring kueri itu alih-alih menambahkan daftar id panjang yang sewenang-wenang ... Anda bisa menggunakan rentang jika id memang mengikuti pola dalam contoh Anda:
Pilihan lain adalah menambahkan pilih dalam:
sumber