Saya hanya ingin tahu mengapa permintaan agregat berjalan jauh lebih cepat dengan GROUP BY
klausa daripada tanpa satu.
Misalnya, kueri ini membutuhkan waktu hampir 10 detik untuk dijalankan
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
Sementara yang ini membutuhkan waktu kurang dari satu detik
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
Hanya ada satu CreatedDate
dalam kasus ini, jadi kueri yang dikelompokkan mengembalikan hasil yang sama dengan yang tidak dikelompokkan.
Saya perhatikan rencana eksekusi untuk dua kueri berbeda - Kueri kedua menggunakan Paralelisme sedangkan kueri pertama tidak.
Apakah normal untuk server SQL untuk mengevaluasi permintaan agregat berbeda jika tidak memiliki klausa GROUP BY? Dan apakah ada sesuatu yang bisa saya lakukan untuk meningkatkan kinerja permintaan 1 tanpa menggunakan GROUP BY
klausa?
Edit
Saya baru belajar saya dapat menggunakan OPTION(querytraceon 8649)
untuk mengatur biaya paralelisme ke 0, yang membuat permintaan menggunakan paralelisme dan mengurangi runtime menjadi 2 detik, meskipun saya tidak tahu apakah ada kerugian untuk menggunakan petunjuk permintaan ini.
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
OPTION(querytraceon 8649)
Saya masih lebih suka runtime yang lebih pendek karena kueri dimaksudkan untuk mengisi nilai pada pilihan pengguna, jadi idealnya seketika seperti kueri yang dikelompokkan. Saat ini saya hanya membungkus pertanyaan saya, tetapi saya tahu itu bukan solusi yang ideal.
SELECT Min(CreatedDate)
FROM
(
SELECT Min(CreatedDate) as CreatedDate
FROM MyTable WITH (NOLOCK)
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
) as T
Edit # 2
Menanggapi permintaan Martin untuk info lebih lanjut :
Keduanya CreatedDate
dan SomeIndexedValue
memiliki indeks non-unik dan non-cluster terpisah. SomeIndexedValue
sebenarnya adalah bidang varchar (7), meskipun ia menyimpan nilai numerik yang menunjuk ke PK (int) dari tabel lain. Hubungan antara dua tabel tidak didefinisikan dalam database. Saya tidak seharusnya mengubah database sama sekali, dan hanya dapat menulis kueri yang meminta data.
MyTable
berisi lebih dari 3 juta catatan, dan setiap catatan ditetapkan ke grup tempat ( SomeIndexedValue
). Grup dapat berkisar dari 1 hingga 200.000 catatan
MAXDOP
menetapkan tingkat paralelisme maksimum, yang membatasi jumlah prosesor yang dapat digunakan kueri. Ini pada dasarnya akan membuat kueri ke-2 berjalan lambat seperti yang ke-1, karena ia menghilangkan kemampuannya untuk menggunakan paralelisme, yang bukan yang saya inginkan.Menurut pendapat saya alasan untuk masalah ini adalah bahwa pengoptimal server sql tidak mencari rencana TERBAIK melainkan mencari rencana yang baik, seperti terbukti dari fakta bahwa setelah memaksa paralelisme kueri dieksekusi lebih cepat, sesuatu yang dimiliki pengoptimal memiliki tidak dilakukan sendiri.
Saya juga telah melihat banyak situasi di mana penulisan ulang kueri dalam format yang berbeda adalah perbedaan antara paralelisasi (misalnya meskipun sebagian besar artikel tentang SQL merekomendasikan parameterisasi saya telah menemukan hal itu menyebabkan kadang-kadang tidak dapat menyejajarkan bahkan ketika parameter mengendus sama dengan non - diparalelkan, atau menggabungkan dua pertanyaan dengan UNION ALL terkadang dapat menghilangkan paralelisasi).
Dengan demikian solusi yang tepat mungkin dengan mencoba berbagai cara penulisan kueri, seperti mencoba tabel temp, variabel tabel, cte, tabel turunan, parameterisasi, dan sebagainya, dan juga bermain dengan indeks, tampilan indeks, atau indeks yang difilter dalam memesan untuk mendapatkan rencana terbaik.
sumber