Saya mencoba mencari tahu apakah ada baris dalam tabel. Menggunakan MySQL, lebih baik melakukan kueri seperti ini:
SELECT COUNT(*) AS total FROM table1 WHERE ...
dan periksa untuk melihat apakah totalnya bukan nol atau lebih baik melakukan kueri seperti ini:
SELECT * FROM table1 WHERE ... LIMIT 1
dan periksa untuk melihat apakah ada baris yang dikembalikan?
Di kedua kueri, klausa WHERE menggunakan indeks.
sql
mysql
performance
exists
Bernard Chen
sumber
sumber
...EXISTS( SELECT 1/0 FROM someothertable)
. Untuk SQL Server & Oracle - tidak ada bedanya untuk menggunakan *, 1 atau NULL karena ADA hanya menguji boolean berdasarkan 1+ dari pencocokan kriteria WHERE.SELECT 1 FROM table1 WHERE col = $var LIMIT 1
ini lebih cepat dari permintaan Anda. Jadi, apa keunggulan permintaan Anda?Saya telah melakukan beberapa penelitian tentang masalah ini baru-baru ini. Cara menerapkannya harus berbeda jika bidangnya adalah bidang TEKS, bidang yang tidak unik.
Saya telah membuat beberapa tes dengan bidang TEKS. Mempertimbangkan fakta bahwa kita memiliki tabel dengan entri 1M. 37 entri sama dengan 'sesuatu':
SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1
denganmysql_num_rows()
: 0,039061069488525s. (LEBIH CEPAT)SELECT count(*) as count FROM test WHERE text LIKE '%something%
: 16.028197050095s.SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%')
: 0.87045907974243s.SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%' LIMIT 1)
: 0,044898986816406s.Tetapi sekarang, dengan bidang BIGINT PK, hanya satu entri yang sama dengan '321321':
SELECT * FROM test2 WHERE id ='321321' LIMIT 1
denganmysql_num_rows()
: 0,0089840888977051s.SELECT count(*) as count FROM test2 WHERE id ='321321'
: 0,00033879280090332s.SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321')
: 0,00023889541625977s.SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321' LIMIT 1)
: 0,00020313262939453s. (LEBIH CEPAT)sumber
SELECT 1 FROM test WHERE texte LIKE '%something%' LIMIT 1
select 1 ... limit 1
, tidak ada gunanya dikelilingi dengan pilih yang adaSELECT 1 FROM test WHERE ...
, tanpaSELECT EXISTS
di sekitarnya. Agaknya rambut lebih cepat seperti itu.Contoh singkat jawaban @ ChrisThompson
Contoh:
Menggunakan alias:
sumber
Dalam penelitian saya, saya dapat menemukan hasilnya dengan mengikuti kecepatan.
sumber
Saya merasa perlu untuk menunjukkan, meskipun tersentuh dalam komentar, bahwa dalam situasi ini:
Lebih unggul dari:
Ini karena kueri pertama dapat dipenuhi oleh indeks, sedangkan kueri kedua membutuhkan pencarian baris (kecuali mungkin semua kolom tabel dalam indeks yang digunakan).
Menambahkan
LIMIT
klausa memungkinkan mesin berhenti setelah menemukan baris apa pun.Kueri pertama harus sebanding dengan:
Yang mengirimkan sinyal yang sama ke mesin (1 / * tidak ada bedanya di sini), tapi saya masih menulis 1 untuk memperkuat kebiasaan ketika menggunakan
EXISTS
:Mungkin masuk akal untuk menambahkan
EXISTS
pembungkus jika Anda membutuhkan pengembalian eksplisit ketika tidak ada baris yang cocok.sumber
Sarankan Anda untuk tidak menggunakan
Count
karena hitungan selalu membuat beban tambahan untuk penggunaan dbSELECT 1
dan itu mengembalikan 1 jika catatan Anda di sana jika tidak kembali nol dan Anda dapat menanganinya.sumber
Sebuah COUNT query lebih cepat, meskipun mungkin tidak terasa, tapi sejauh mendapatkan hasil yang diinginkan, baik harus memadai.
sumber
Terkadang cukup berguna untuk mendapatkan kunci primer kenaikan otomatis (
id
) dari baris jika ada dan0
jika tidak.Inilah cara ini dapat dilakukan dalam satu permintaan:
sumber
IFNULL(id, 0)
sini sajaCOUNT(*)
?Untuk tabel non-InnoDB Anda juga bisa menggunakan tabel skema informasi:
http://dev.mysql.com/doc/refman/5.1/en/tables-table.html
sumber
Saya akan pergi dengan
COUNT(1)
. Lebih cepat daripadaCOUNT(*)
karenaCOUNT(*)
tes untuk melihat apakah setidaknya satu kolom di baris itu! = NULL. Anda tidak memerlukan itu, terutama karena Anda sudah memiliki kondisi (WHERE
klausa).COUNT(1)
alih-alih menguji validitas1
, yang selalu valid dan membutuhkan waktu lebih sedikit untuk menguji.sumber
Atau Anda dapat memasukkan bagian sql mentah ke ketentuan sehingga saya memiliki 'conditions' => array ('Member.id TIDAK DALAM (SELECT Membership.member_id DARI keanggotaan menjadi AS Keanggotaan)')
sumber
COUNT(*)
dioptimalkan dalam MySQL, sehingga permintaan sebelumnya cenderung lebih cepat, secara umum.sumber