Saya memiliki banyak baris yang harus saya masukkan ke dalam tabel, tetapi sisipan ini selalu dilakukan dalam batch. Jadi saya ingin memeriksa apakah satu baris dari batch ada di tabel karena saya tahu mereka semua dimasukkan.
Jadi ini bukan pemeriksaan kunci utama, tetapi seharusnya tidak terlalu penting. Saya hanya ingin memeriksa satu baris jadi count(*)
mungkin tidak baik, jadi sepertinya exists
saya kira.
Tapi karena saya cukup baru di PostgreSQL saya lebih suka bertanya kepada orang yang tahu.
Batch saya berisi baris dengan struktur berikut:
userid | rightid | remaining_count
Jadi jika tabel berisi baris dengan ketentuan userid
itu berarti mereka semua ada di sana.
sql
postgresql
Valentin Kuzub
sumber
sumber
Jawaban:
Gunakan kata kunci EXISTS untuk TRUE / FALSE return:
sumber
select exists(select 1 from contact where id=12) AS "exists"
exists
ataulimit 1
saya memiliki penurunan kinerja yang kuat karena Postgres menggunakan Seq Scan daripada Index Scan. Dananalyze
tidak membantu.Bagaimana dengan sederhana:
di mana
123
userid dari batch yang akan Anda masukkan.Kueri di atas akan mengembalikan kumpulan kosong atau satu baris, tergantung pada apakah ada catatan dengan userid yang diberikan.
Jika ini ternyata terlalu lambat, Anda bisa melihat membuat indeks
tbl.userid
.Agar ini tetap benar bahkan jika program Anda terganggu mid-batch, saya sarankan Anda memastikan Anda mengelola transaksi basis data dengan tepat (yaitu bahwa seluruh batch dimasukkan dalam satu transaksi tunggal).
sumber
COUNT
bertindak pada bersarangSELECT
yang memiliki paling banyak 1 baris (karenaLIMIT
dalam subquery).BTW: jika Anda ingin seluruh kumpulan gagal jika duplikat, maka (diberi batasan kunci utama)
akan melakukan apa yang Anda inginkan: itu berhasil, atau gagal.
sumber
Saya percaya bahwa ini adalah kueri yang digunakan postgres untuk memeriksa kunci asing.
Dalam kasus Anda, Anda bisa melakukan ini sekaligus:
sumber
seperti yang ditunjukkan @MikeM.
dengan indeks pada kontak, biasanya dapat mengurangi biaya waktu menjadi 1 ms.
sumber
Jika resultset Anda berisi baris maka Anda tidak perlu memasukkan. Kalau tidak, masukkan catatan Anda.
sumber
Jika Anda berpikir tentang performace, mungkin Anda dapat menggunakan "PERFORM" dalam suatu fungsi seperti ini:
sumber
Saya ingin mengusulkan pikiran lain untuk secara khusus menangani kalimat Anda: "Jadi saya ingin memeriksa apakah satu baris dari batch yang ada di meja karena kemudian saya tahu mereka semua yang dimasukkan ."
Anda membuat hal-hal efisien dengan memasukkan "batch" tetapi kemudian melakukan pemeriksaan keberadaan satu catatan pada suatu waktu? Ini tampaknya kontra intuitif bagi saya. Jadi, ketika Anda mengatakan " sisipan selalu dilakukan dalam batch " saya menganggap Anda berarti Anda memasukkan banyak catatan dengan satu pernyataan insert . Anda perlu menyadari bahwa Postgres sesuai dengan ACID. Jika Anda menyisipkan beberapa catatan (kumpulan data) dengan satu pernyataan masukkan , tidak perlu memeriksa apakah ada yang dimasukkan atau tidak. Pernyataan itu lulus atau akan gagal. Semua catatan akan dimasukkan atau tidak ada.
Di sisi lain, jika kode C # Anda hanya melakukan "set" pernyataan insert yang terpisah, misalnya, dalam satu lingkaran, dan dalam pikiran Anda, ini adalah "batch" .. maka Anda seharusnya tidak menggambarkannya sebagai " sisipan selalu dilakukan dalam batch ". Fakta bahwa Anda mengharapkan bagian dari apa yang Anda sebut "batch", mungkin sebenarnya tidak dimasukkan, dan karenanya merasakan perlunya pemeriksaan, sangat menunjukkan hal ini, dalam hal ini Anda memiliki masalah yang lebih mendasar. Anda perlu mengubah paradigma Anda untuk benar-benar menyisipkan banyak catatan dengan satu sisipan, dan lupakan memeriksa apakah catatan individual membuatnya.
Pertimbangkan contoh ini:
Ini sebenarnya adalah paradigma untuk setiap ACID compliant DB .. bukan hanya Postgresql. Dengan kata lain Anda lebih baik jika Anda memperbaiki konsep "batch" Anda dan menghindari harus melakukan pemeriksaan baris demi baris di tempat pertama.
sumber