Saya ingin tahu apakah saya memiliki kueri bergabung seperti ini -
Select E.Id,E.Name from Employee E join Dept D on E.DeptId=D.Id
dan subkueri seperti ini -
Select E.Id,E.Name from Employee Where DeptId in (Select Id from Dept)
Saat saya mempertimbangkan kinerja, manakah dari dua kueri yang akan lebih cepat dan mengapa ?
Juga adakah waktu ketika saya harus memilih salah satu daripada yang lain?
Maaf jika ini terlalu sepele dan ditanyakan sebelumnya tapi saya bingung. Juga, akan lebih bagus jika kalian bisa menyarankan saya alat yang harus saya gunakan untuk mengukur kinerja dua pertanyaan. Terima kasih banyak!
sql
performance
sql-server-2008
subquery
join
Vishal
sumber
sumber
Jawaban:
Saya akan MENGHARAPKAN kueri pertama menjadi lebih cepat, terutama karena Anda memiliki persamaan dan GABUNG eksplisit. Menurut pengalaman saya
IN
adalah operator yang sangat lambat, karena SQL biasanya mengevaluasinya sebagai serangkaianWHERE
klausa yang dipisahkan oleh "OR" (WHERE x=Y OR x=Z OR...
).Seperti halnya SEMUA HAL SQL, jarak tempuh Anda mungkin berbeda. Kecepatan akan sangat bergantung pada indeks (apakah Anda memiliki indeks pada kedua kolom ID? Itu akan sangat membantu ...) antara lain.
Satu-satunya cara NYATA untuk mengetahui dengan kepastian 100% mana yang lebih cepat adalah dengan mengaktifkan pelacakan kinerja (Statistik IO sangat berguna) dan menjalankan keduanya. Pastikan untuk menghapus cache Anda di antara proses!
sumber
Saya yakin ini adalah pertanyaan "Tua tapi Emas". Jawabannya adalah, tergantung!". Pertunjukan adalah subjek yang sangat sensitif sehingga akan terlalu konyol untuk mengatakan: "Jangan pernah menggunakan subkueri, selalu bergabung". Di tautan berikut, Anda akan menemukan beberapa praktik terbaik dasar yang menurut saya sangat membantu:
Saya memiliki tabel dengan 50000 elemen, hasil yang saya cari adalah 739 elemen.
Pertanyaan saya pada awalnya adalah ini:
dan butuh waktu 7,9 detik untuk mengeksekusinya.
Permintaan saya akhirnya adalah ini:
dan butuh 0,0256 detik
SQL bagus, bagus.
sumber
Mulailah melihat rencana eksekusi untuk melihat perbedaan bagaimana SQl Server akan menafsirkannya. Anda juga dapat menggunakan Profiler untuk benar-benar menjalankan kueri beberapa kali dan mendapatkan perbedaannya.
Saya tidak akan berharap ini menjadi sangat berbeda, di mana Anda bisa mendapatkan keuntungan kinerja yang nyata dan besar dalam menggunakan gabungan daripada subkueri adalah ketika Anda menggunakan subkueri yang berkorelasi.
EXISTS sering kali lebih baik daripada salah satu dari keduanya dan ketika Anda berbicara left join di mana Anda ingin semua record tidak ada di tabel left join, maka NOT EXISTS sering kali merupakan pilihan yang jauh lebih baik.
sumber
Performa didasarkan pada jumlah data yang Anda jalankan pada ...
Jika kurang data sekitar 20k. JOIN bekerja lebih baik.
Jika datanya lebih seperti 100k + maka IN bekerja lebih baik.
Jika Anda tidak membutuhkan data dari tabel lain, IN bagus, Tapi selalu lebih baik untuk yang sudah ada.
Semua kriteria ini saya uji dan tabel memiliki indeks yang sesuai.
sumber
Performanya harus sama; jauh lebih penting untuk menerapkan indeks dan pengelompokan yang benar pada tabel Anda (terdapat beberapa sumber daya yang bagus tentang topik itu).
(Diedit untuk mencerminkan pertanyaan yang diperbarui)
sumber
Kedua kueri tersebut mungkin tidak setara secara semantik. Jika seorang karyawan bekerja untuk lebih dari satu departemen (mungkin di perusahaan tempat saya bekerja; memang, ini berarti tabel Anda tidak sepenuhnya dinormalisasi) maka kueri pertama akan mengembalikan baris duplikat sedangkan kueri kedua tidak. Untuk membuat kueri setara dalam kasus ini,
DISTINCT
kata kunci harus ditambahkan keSELECT
klausa, yang mungkin berdampak pada kinerja.Perhatikan ada aturan praktis desain yang menyatakan tabel harus memodelkan entitas / kelas atau hubungan antara entitas / kelas tetapi tidak keduanya. Oleh karena itu, saya sarankan Anda membuat tabel ketiga, misalnya
OrgChart
, untuk memodelkan hubungan antara karyawan dan departemen.sumber
Saya tahu ini adalah posting lama, tetapi saya pikir ini adalah topik yang sangat penting, terutama saat ini di mana kami memiliki lebih dari 10 juta catatan dan berbicara tentang terabyte data.
Saya juga akan memberi bobot pada observasi berikut. Saya memiliki sekitar 45 juta catatan di tabel saya ([data]), dan sekitar 300 catatan di tabel [kucing] saya. Saya memiliki pengindeksan ekstensif untuk semua kueri yang akan saya bicarakan.
Pertimbangkan Contoh 1:
versus Contoh 2:
Contoh 1 membutuhkan waktu sekitar 23 menit untuk dijalankan. Contoh 2 membutuhkan waktu sekitar 5 menit.
Jadi saya akan menyimpulkan bahwa sub-query dalam kasus ini jauh lebih cepat. Tentu saja perlu diingat bahwa saya menggunakan drive SSD M.2 yang berkemampuan i / o @ 1GB / detik (itu byte bukan bit), jadi indeks saya juga sangat cepat. Jadi ini juga dapat memengaruhi kecepatan dalam keadaan Anda
Jika ini adalah pembersihan data satu kali, mungkin yang terbaik adalah membiarkannya berjalan dan menyelesaikannya. Saya menggunakan TOP (10000) dan melihat berapa lama dan mengalikannya dengan jumlah record sebelum saya mencapai permintaan besar.
Jika Anda mengoptimalkan database produksi, saya sangat menyarankan data pra-pemrosesan, yaitu gunakan pemicu atau perantara kerja untuk memperbarui catatan asinkron, sehingga akses waktu nyata mengambil data statis.
sumber
Anda dapat menggunakan Rencana Jelaskan untuk mendapatkan jawaban yang obyektif.
Untuk masalah Anda, filter Yang Ada mungkin akan bekerja paling cepat.
sumber