Anda mungkin menemukan kueri yang memiliki masalah dengan parameter sniffing, yang berkaitan dengan bagaimana Sql Server mencoba mengoptimalkan rencana eksekusi kueri Anda, tetapi dalam kasus ketika Layanan Pelaporan terlibat benar-benar mengacaukannya dan membuatnya berjalan sangat lambat.
Saya memiliki kasus dengan laporan yang memiliki dua kueri kompleks masing-masing sekitar 150 baris tetapi berjalan dalam 7 detik di lingkungan pengembangan saya - seluruh laporan membutuhkan waktu kurang dari 10 detik. Namun, ketika disebarkan ke server SSRS produksi, laporan membutuhkan waktu lebih dari 7 menit dan sering kali kehabisan waktu sehingga laporan tidak dapat dijalankan.
Sebagian besar informasi tentang masalah ini membicarakannya sehubungan dengan prosedur tersimpan. Jangan abaikan ini karena Anda tidak menggunakan prosedur tersimpan (seperti yang saya lakukan untuk waktu yang lama); itu sangat relevan dengan kueri Sql langsung juga.
Jadi perbedaan yang Anda lihat adalah bahwa Sql Server membuat dua rencana eksekusi yang sangat berbeda karena kedua kueri tersebut terstruktur secara berbeda.
Untungnya, solusinya sangat sederhana:masukkan parameter ke dalam variabel internal dan gunakan ini dalam kueri Anda. Saya melakukan ini dengan laporan saya dan laporan produksi kembali ke 10 detik seperti yang dilakukan versi pengembangan di Visual Studio.
Untuk melewati sniffing parameter untuk kueri pertama Anda, Anda akan membuatnya terlihat seperti ini:
BEGIN
-- Use internal variables to solve parameter sniffing issues
DECLARE @StartDateInternal AS DATETIME;
DECLARE @EndDateInternal AS DATETIME;
DECLARE @SchoolIDInternal AS INT;
DECLARE @GradeLevelInternal AS INT;
-- Copy the parameters into the internal variables
SET @StartDateInternal = @StartDate;
SET @EndDateInternal = @EndDate;
SET @SchoolIDInternal = @SchoolID;
SET @GradeLevelInternal = @GradeLevel;
-- Now use the internal variables in your query rather than the parameters
SELECT
c.TeacherID, u.FName + ' ' + u.lname as Teacher, count(sb.behaviorID) as BxCount,
sb.behaviorID, b.BehaviorName, std.GradeID, gl.GradeLevel
FROM
StudentBehaviors sb
join
Classes c on sb.classid = c.classid
join
StudentDetails std on sb.studentID = std.StudentID and std.RecordIsActive=1
join
users u on c.TeacherID = u.UserID
join
Behaviors b on sb.behaviorID = b.BehaviorID
join
GradeLevels gl on std.GradeID = gl.GradeLevelID
WHERE
sb.classdate between @StartDateInternal and @EndDateInternal
and c.schoolid = @SchoolIDInternal
and std.GradeID = @GradeLevelInternal
GROUP BY
c.TeacherID, sb.behaviorID, b.BehaviorName, u.lname, u.FName,
std.GradeID, gl.GradeLevel
ORDER BY
u.LName, sb.behaviorID;
END;