Seperti judulnya ... Saya mencoba mencari cara tercepat dengan overhead paling sedikit untuk menentukan apakah ada catatan dalam tabel atau tidak.
Permintaan sampel:
SELECT COUNT(*) FROM products WHERE products.id = ?;
vs
SELECT COUNT(products.id) FROM products WHERE products.id = ?;
vs
SELECT products.id FROM products WHERE products.id = ?;
Katakanlah ?
bertukar dengan 'TB100'
... baik kueri pertama dan kedua akan mengembalikan hasil yang sama persis (katakanlah ... 1
untuk percakapan ini). Permintaan terakhir akan kembali 'TB100'
seperti yang diharapkan, atau tidak ada jika id
tidak ada dalam tabel.
Tujuannya adalah untuk mengetahui apakah id
ada di dalam tabel atau tidak. Jika tidak, program selanjutnya akan memasukkan catatan, jika ya, program akan melewatkannya atau melakukan kueri UPDATE berdasarkan logika program lain di luar cakupan pertanyaan ini.
Mana yang lebih cepat dan memiliki lebih sedikit overhead? (Ini akan diulang puluhan ribu kali per program yang dijalankan, dan akan dijalankan berkali-kali sehari).
(Menjalankan kueri ini terhadap M $ SQL Server dari Java melalui driver JDBC yang disediakan M $)
sumber
if exists(select null from products where id = @id)
; jika dalam kueri dipanggil langsung oleh klienselect case when exists (...) then 1 else 0 end
.Jawaban:
SELECT TOP 1 products.id FROM products WHERE products.id = ?;
akan mengungguli semua saran Anda karena akan menghentikan eksekusi setelah menemukan catatan pertama.sumber
id
bukan PK. Jadi +1 atas saran Anda.EXISTS
(atauNOT EXISTS
) dirancang khusus untuk memeriksa apakah ada sesuatu dan karenanya (dan) pilihan terbaik. Ini akan berhenti pada baris pertama yang cocok sehingga tidak memerlukanTOP
klausa dan tidak benar-benar memilih data sehingga tidak ada overhead dalam ukuran kolom. Anda dapat menggunakan dengan aman diSELECT *
sini - tidak berbeda dariSELECT 1
,SELECT NULL
atauSELECT AnyColumn
... (Anda bahkan dapat menggunakan ekspresi tidak valid sepertiSELECT 1/0
dan tidak akan rusak) .sumber
Exists
bekerja denganselect
sedemikian rupa sehingga keluar segera setelah satu baris ditemukan. Lebih lanjut ada hanya mencatat keberadaan catatan, bukan nilai aktual dalam catatan, menghemat kebutuhan untuk memuat baris dari disk (tentu saja dengan asumsi kriteria pencarian diindeks). Adapun overheadif
- Anda harus menghabiskan waktu yang sangat kecil ini.select top
atauexists
; jika tidak ada, mesin sql harus melakukan pemindaian tabel. Ini adalah opsi pencarian tabel yang paling tidak diinginkan. Jika Anda tidak berwenang membuat indeks, Anda harus berkomunikasi dengan staf teknis di sisi lain untuk mengetahui apakah mereka menyesuaikan secara otomatis atau mereka mengharapkan Anda untuk menyarankan indeks.SELECT CASE WHEN EXISTS(..) THEN 1 ELSE 0 END;
Tidak ada yang bisa mengalahkan -
Anda tidak perlu menghitung untuk mengetahui apakah ada data dalam tabel. Dan jangan gunakan alias saat tidak diperlukan.
sumber
id
bukan kunci utama. Jadi, meskipun Anda tidak menghitung Anda masih perlu menemukan semua catatan yang cocok, mungkin ribuan dari mereka. Tentang aliasing - kode adalah pekerjaan konstan yang sedang berjalan. Anda tidak pernah tahu kapan Anda harus kembali. Aliasing membantu mencegah kesalahan runtime yang bodoh; misalnya, nama kolom unik yang tidak memerlukan alias tidak lagi unik karena seseorang membuat kolom dengan nama yang sama di tabel gabungan lainnya.aliasing
. Istilah yang benar adalahqualifying
. Berikut ini penjelasan yang lebih panjang dari Alex Kuznetzov . Tentang kueri tabel tunggal - ini adalah tabel tunggal sekarang . Tetapi kemudian, ketika bug ditemukan dan Anda mencoba untuk menahan banjir, klien gugup, Anda bergabung dengan meja lain hanya untuk menghadapi pesan kesalahan - pesan yang mudah dikoreksi, tetapi tidak pada saat berkeringat ini, serangan stroke kecil - dan Anda memperbaiki kesalahan mengingat tidak pernah meninggalkan kolom ...Pendekatan ini mengembalikan boolean untuk Anda.
sumber
Anda juga bisa menggunakan
sumber
Jangan berpikir ada orang yang menyebutkannya, tetapi jika Anda yakin data tidak akan berubah di bawah Anda, Anda mungkin ingin juga menerapkan petunjuk NoLock untuk memastikannya tidak diblokir saat membaca.
sumber
Ini adalah solusi basis data lintas relasional yang berfungsi di semua basis data.
sumber
Di bawah ini adalah cara termudah dan tercepat untuk menentukan apakah ada catatan dalam database atau tidak. Untung itu berfungsi di semua DB Relasional
sumber
sumber
Saya telah menggunakan ini di masa lalu dan tidak memerlukan pemindaian tabel penuh untuk melihat apakah ada sesuatu. Ini sangat cepat ...
sumber
Bagi mereka yang menemukan ini dari latar belakang MySQL atau Oracle - MySQL mendukung klausa LIMIT untuk memilih sejumlah catatan, sementara Oracle menggunakan ROWNUM.
sumber