Ini adalah pertanyaan sederhana yang sepertinya tidak bisa saya temukan jawabannya.
Dalam hal kinerja, Jika saya memiliki WHERE
klausa seperti a=0 and b=0 and ... z=0
, Apakah saya akan mendapatkan kinerja apa pun jika saya mengganti kondisi itu dengan a+b+...+z=0
?
Dengan kata lain, apakah ada perolehan kinerja dengan mengganti yang berikut ini
Select *
From MyTable
Where A=0 and B=0 and C=0 and D=0...
Dengan
Select *
From MyTable
Where A+B+C+D=0...
Saya tahu ini bisa bergantung pada indeks, tetapi untuk tujuan ini, anggap saja tidak ada indeks. Apakah operator aritmatika (+) berkinerja lebih baik daripada Operator Logika "ATAU" atau "DAN"?
Saya mendapat kesan bahwa penambahan berkinerja lebih baik daripada beberapa kondisi dengan AND atau OR.
Hasil tes
Di Meja dengan 4,2 juta baris
Mengembalikan baris Di mana A = 0 B = 0 dan C = 0 -> 351748 Baris
Penambahan (A + B + C = 0) mengambil 5 detik sedangkan kondisi Logika A = 0 dan B = 0 dan C = 0 butuh 11 detik.
Di samping itu
Mengembalikan baris di mana A <> 0 B <> 0 atau C <> 0 -> 3829750 Baris 58 detik
Mengembalikan baris Di mana F65 + F67 + f64 <> 0 -> 3829750 Baris 57 detik
Untuk OR, tampaknya tidak ada perbedaan yang signifikan.
Saya setuju dengan gbn:
Jika A adalah -1 dan B adalah 1, A + B = 0 tetapi A = 0 dan B = 0 salah
dan dengan AMtwo:
ABS (A) + ABS (B) + ABS (C) + ABS (D) ... Bahkan jika Anda hanya mengharapkan nilai positif, jika kolom menerima nilai negatif, Anda harus mengasumsikan bahwa Anda mungkin menemukan satu
Hasilnya sangat mengesankan, seperti yang saya pikirkan, Tampaknya penambahannya jauh lebih cepat daripada operator logis.
A = Float, B = Uang dan C = Float. Permintaan yang digunakan adalah seperti yang ditunjukkan. Dalam kasus saya, semua adalah angka positif. Tidak ada indeks. Masuk akal dalam pikiran saya bahwa penambahan akan lebih cepat daripada kondisi logis!
Jawaban:
Dalam pertanyaan Anda, Anda merinci beberapa tes yang telah disiapkan di tempat Anda "membuktikan" bahwa opsi tambahan lebih cepat daripada membandingkan kolom diskrit. Saya menduga metodologi pengujian Anda mungkin cacat dalam beberapa cara, seperti @gbn dan @srutzky menyinggung.
Pertama, Anda perlu memastikan Anda tidak menguji SQL Server Management Studio (atau klien apa pun yang Anda gunakan). Misalnya, jika Anda menjalankan
SELECT *
dari tabel dengan 3 juta baris, Anda sebagian besar menguji kemampuan SSMS untuk menarik baris dari SQL Server dan membuat mereka di layar. Anda jauh lebih baik menggunakan sesuatuSELECT COUNT(1)
yang meniadakan kebutuhan untuk menarik jutaan baris di jaringan, dan menampilkannya di layar.Kedua, Anda harus mengetahui cache data SQL Server. Biasanya, kami menguji kecepatan membaca data dari penyimpanan, dan memproses data itu, dari cold-cache (yaitu buffer SQL Server kosong). Kadang-kadang, masuk akal untuk melakukan semua pengujian Anda dengan cache hangat, tetapi Anda perlu mendekati pengujian Anda secara eksplisit dengan mempertimbangkan hal itu.
Untuk tes cold-cache, Anda harus menjalankan
CHECKPOINT
danDBCC DROPCLEANBUFFERS
sebelum menjalankan setiap tes.Untuk tes yang Anda tanyakan dalam pertanyaan Anda, saya membuat test-bed berikut:
Ini mengembalikan jumlah 260.144.641 pada mesin saya.
Untuk menguji metode "penambahan", saya menjalankan:
Tab pesan menunjukkan:
Untuk tes "kolom diskrit":
lagi, dari tab pesan:
Dari statistik di atas Anda dapat melihat varian kedua, dengan kolom diskrit dibandingkan dengan 0, waktu yang berlalu sekitar 10 detik lebih pendek, dan waktu CPU sekitar 6 kali lebih sedikit. Durasi lama dalam pengujian saya di atas sebagian besar merupakan hasil dari membaca banyak baris dari disk. Jika Anda menurunkan jumlah baris menjadi 3 juta, Anda melihat rasio tetap hampir sama tetapi waktu yang berlalu turun secara nyata, karena disk I / O memiliki efek yang jauh lebih sedikit.
Dengan metode "Tambahan":
Dengan metode "kolom diskrit":
Apa yang akan membuat perbedaan yang sangat besar untuk tes ini? Indeks yang sesuai, seperti:
Metode "penambahan":
Metode "kolom diskrit":
Rencana eksekusi untuk setiap permintaan (dengan indeks di atas di tempat) cukup jelas.
Metode "penambahan", yang harus melakukan pemindaian seluruh indeks:
dan metode "kolom diskrit", yang dapat mencari ke baris pertama indeks di mana kolom indeks utama
A
, adalah nol:sumber
Katakanlah Anda memiliki indeks pada A, B, C, dan D. Bisa juga difilter.
Ini lebih cenderung menggunakan indeks daripada penambahan.
Dalam berita lain, Jika A adalah -1 dan B adalah 1,
A+B=0
itu benar tetapiA=0 and B=0
salah.sumber
(Harap perhatikan bahwa jawaban ini diajukan sebelum pengujian apa pun dicatat dalam Pertanyaan: teks Pertanyaan berakhir tepat di atas bagian Hasil pengujian .)
Saya akan menebak bahwa
AND
kondisi yang terpisah akan lebih disukai karena pengoptimal akan lebih cenderung melakukan hubungan pendek operasi jika satu dari mereka tidak sama dengan 0, tanpa perlu melakukan perhitungan terlebih dahulu.Namun, karena ini adalah masalah kinerja, Anda harus terlebih dahulu menyiapkan tes untuk menentukan jawaban pada perangkat keras Anda . Laporkan hasil itu, tunjukkan kode pengujian Anda, dan minta orang lain untuk memeriksanya untuk memastikan itu adalah tes yang baik. Mungkin ada faktor-faktor lain yang patut dipertimbangkan yang tidak Anda pikirkan.
sumber
Beberapa alasan umum, jika Anda tidak memiliki indeks di tangan saya tidak berpikir itu akan menjadi masalah yang mana dari dua solusi yang Anda pilih, keduanya akan berkinerja buruk. Jika Anda di sisi lain memiliki indeks pada satu atau lebih kolom dalam predikat, yang pertama kemungkinan akan berkinerja lebih baik daripada yang kedua, karena yang kedua mungkin tidak akan dapat menggunakan indeks.
Disjunctions (OR) secara umum berkinerja lebih buruk daripada conjunctions (AND), tetapi bahkan jika Anda memiliki kueri dengan disjunctions, saya akan menempatkan uang saya pada yang pertama.
sumber
Tidak, bukan. Pertanyaan (semacam) ini adalah apa yang mengganggu banyak DBA dan pengembang perangkat lunak setiap hari, dan itu semua hanya sepele.
Ya, tidak akan. Setidaknya bukan jawaban umum. Pertama-tama, itu akan sangat tergantung pada RDBMS mana yang Anda gunakan (OK, Anda menggunakan sql-server , tapi tetap saja). Bahkan mungkin berubah ketika Anda beralih dari satu versi RDBMS Anda ke yang berikutnya.
Kemudian, itu dapat bergantung pada jumlah detail kecil lainnya, misalnya bagaimana DB Anda menyimpan data, jika Anda memiliki sub-seleksi / gabungan yang mengacaukan masalah pengoptimal paket, dll. Pengoptimal mungkin memberikan Anda berbagai paket eksekusi tergantung pada berapa banyak baris yang Anda miliki ...
Melakukan tes dunia nyata biasanya satu-satunya cara yang berguna untuk menyelesaikan pertanyaan seperti ini. Juga, setiap keuntungan yang didapat oleh optimisasi "misterius" seperti ini biasanya ditelan sepuluh kali lipat oleh pilihan indeks yang cerdas, jadi saya tidak akan repot-repot menghabiskan terlalu banyak waktu untuk menggunakannya, sebelum penggunaan indeks benar-benar dikesampingkan.
sumber
Ini mungkin jelas, tetapi jika kolomnya
INT
, makaa+b+c
bisa sama dengan nol bahkan ketika tidak ada satupun yang benar-benar nol. Anda sedang menguji dua hal yang berbeda!sumber