Saya perlu menulis kueri untuk mengambil daftar besar id.
Kami mendukung banyak backend (MySQL, Firebird, SQLServer, Oracle, PostgreSQL ...) jadi saya perlu menulis SQL standar.
Ukuran set id bisa besar, kueri akan dihasilkan secara terprogram. Jadi, apa pendekatan terbaik?
1) Menulis kueri menggunakan IN
SELECT * FROM TABLE WHERE ID IN (id1, id2, ..., idn)
Pertanyaan saya di sini adalah. Apa yang terjadi jika n sangat besar? Juga, bagaimana dengan kinerja?
2) Menulis kueri menggunakan OR
SELECT * FROM TABLE WHERE ID = id1 OR ID = id2 OR ... OR ID = idn
Saya pikir pendekatan ini tidak memiliki batas n, tetapi bagaimana dengan kinerja jika n sangat besar?
3) Menulis solusi terprogram:
foreach (var id in myIdList)
{
var item = GetItemByQuery("SELECT * FROM TABLE WHERE ID = " + id);
myObjectList.Add(item);
}
Kami mengalami beberapa masalah dengan pendekatan ini ketika server database ditanyai melalui jaringan. Biasanya lebih baik melakukan satu kueri yang mengambil semua hasil dibandingkan membuat banyak kueri kecil. Mungkin aku salah.
Apa solusi yang tepat untuk masalah ini?
IN
! Saya melakukan tambang sebagai solusi Anda 1 + 3. Hanya kueri terakhir adalah satu, string kueri panjang dikirim ke SQL untuk dieksekusi.Jawaban:
Opsi 1 adalah satu-satunya solusi yang baik.
Mengapa?
Opsi 2 melakukan hal yang sama tetapi Anda mengulangi nama kolom berkali-kali; Selain itu mesin SQL tidak segera tahu bahwa Anda ingin memeriksa apakah nilainya adalah salah satu nilai dalam daftar tetap. Namun, mesin SQL yang baik dapat mengoptimalkannya untuk memiliki kinerja yang sama dengan
IN
. Masih ada masalah keterbacaan ...Opsi 3 adalah kinerja-bijaksana hanya mengerikan. Ini mengirimkan kueri setiap loop dan memalu database dengan permintaan kecil. Itu juga mencegahnya menggunakan optimasi apa pun untuk "nilai adalah salah satu dari yang ada dalam daftar"
sumber
Pendekatan alternatif mungkin menggunakan tabel lain untuk memuat nilai id. Tabel lain ini kemudian dapat digabungkan di dalam TABEL Anda untuk membatasi baris yang dikembalikan. Ini akan memiliki keuntungan besar bahwa Anda tidak akan memerlukan SQL dinamis (bermasalah pada saat terbaik), dan Anda tidak akan memiliki klausa IN yang sangat panjang.
Anda akan memotong tabel lain ini, memasukkan banyak baris Anda, lalu mungkin membuat indeks untuk membantu kinerja bergabung. Ini juga akan memungkinkan Anda melepaskan akumulasi baris-baris ini dari pengambilan data, mungkin memberi Anda lebih banyak opsi untuk menyempurnakan kinerja.
Pembaruan : Meskipun Anda bisa menggunakan tabel sementara, saya tidak bermaksud mengatakan bahwa Anda harus atau bahkan harus. Tabel permanen yang digunakan untuk data sementara adalah solusi umum dengan kelebihan di luar yang dijelaskan di sini.
sumber
select
pernyataan di tabel lain. Daftar ini diteruskan sebagai tabel lain yang Andainner join
lawan.Yang disarankan Ed Guiness benar-benar penguat kinerja, saya punya pertanyaan seperti ini
apa yang saya lakukan :
Kemudian bagian dalam bergabung dengan temp dengan tabel utama:
Dan kinerjanya meningkat secara drastis.
sumber
Opsi pertama jelas merupakan pilihan terbaik.
Namun mengingat daftar id sangat besar , katakan jutaan, Anda harus mempertimbangkan ukuran chunk seperti di bawah ini:
Mengapa Anda harus membaginya menjadi potongan-potongan?
Itu selalu bekerja seperti pesona bagi saya. Semoga ini akan bekerja untuk sesama pengembang saya juga :)
sumber
Melakukan SELECT * FROM MyTable where perintah id in () pada tabel Azure SQL dengan 500 juta catatan menghasilkan waktu tunggu> 7 menit!
Melakukan ini sebagai gantinya mengembalikan hasil:
Gunakan gabung.
sumber
Dalam kebanyakan sistem basis data,
IN (val1, val2, …)
dan serangkaianOR
dioptimalkan untuk rencana yang sama.Cara ketiga adalah mengimpor daftar nilai ke tabel sementara dan menggabungkannya yang lebih efisien di sebagian besar sistem, jika ada banyak nilai.
Anda mungkin ingin membaca artikel ini:
sumber
Contoh 3 akan menjadi yang terburuk di antara mereka semua karena Anda menekan database berkali-kali tanpa alasan yang jelas.
Memuat data ke tabel temp dan kemudian bergabung dengan itu akan menjadi yang tercepat. Setelah itu IN harus bekerja sedikit lebih cepat daripada kelompok OR.
sumber
Saya pikir maksud Anda SqlServer tetapi pada Oracle Anda memiliki batas keras berapa banyak elemen IN Anda dapat menentukan: 1000.
sumber