PDA

View Full Version : افزایش زمان اجرای Query در SP!!!!



resident
سه شنبه 18 تیر 1392, 18:56 عصر
دوستان عزیز سلام.
عرض به خدمتتون من یه view نوشتم که در اون 19 جدول با هم join شدن و 50 تا هم ستون داره .
وقتی من دستور select * from person_view رو اجرا می کنم 174000 رکورد در 11 ثانیه نمایش داده می شه.

و اما مشکل اساسی من: من یه SP نوشتم که در اون یه Dynamic Query دارم که برای گرفتن اطلاعات Page هام به کار میره(مثلا میگم اطلاعات صفحه سوم رو بده). اون SP میاد اطلاعات رو از همین view میخونه. جالــــبیش میدونید کجاست؟ اینجا که اگه بگم 20 تا رکورد با همه ستونها بده حدود 2 دقیقه طول می کشه. نمیدونم مشکل از کجاست؟
اینم اون قسمت از SP که میاد Select می کنه.



declare @SQLQuery nvarchar(max)
set @SQLQuery='select '+@SelectedColumn+' from
(select '+@SelectedColumn+',row_number() over (order by '+@PrimaryKeyName+') as RowNumber from '+@ViewName+') t
where ' + @Condition +' and RowNumber >'+cast(@RowNumberFrom as nvarchar(10))+' and RowNumber < '+cast(@RowNumberTo as nvarchar(10))+' order by '+@OrderBy+@OrderByAsc_Desc

EXECUTE sp_executesql @SQLQuery


البته خب طبیعیه که وقتی ستونهای درخواستی رو کمتر می کنم سرعت اجرا بیشتر میشه


مشکل کار کجاست؟ چه کنم؟

in_chand_nafar
سه شنبه 18 تیر 1392, 20:50 عصر
دوست عزیز لطفا Plan کوئری مورد نظرتون رو برای بررسی بیشتر اینجا قرار دهید؟
اوضاع ایندکس ها چه طور است؟
اوضاع Fragmentation جدول و ایندکس هاتون چه طور است؟
در ضمن احتمالا شما مشکل Parameter Sniffing هم داشته باشید

resident
چهارشنبه 19 تیر 1392, 09:33 صبح
in_chand_nafar عزیز ممنونم از زمانی که گذاشتید.

دوست عزیز لطفا Plan کوئری مورد نظرتون رو برای بررسی بیشتر اینجا قرار دهید؟

Execution Plan رو اتچ کردم.


اوضاع ایندکس ها چه طور است؟

روی PK ها و ستونهایی که میخوام مقادیر تکراری نگیرن Index گذاشتم.



اوضاع Fragmentation جدول و ایندکس هاتون چه طور است؟

چیزی در مورد این قضیه نمیدونم.



در ضمن احتمالا شما مشکل Parameter Sniffing هم داشته باشید
در مورد اینم مطالغه کردم انگار مرتبط بود با Index ها. درسته؟

resident
چهارشنبه 19 تیر 1392, 09:37 صبح
راستی یه چیز دیگه در قسمت اول گفتم که وقتی من دستور select * from person_view رو اجرا می کنم 174000 رکورد در 11 ثانیه نمایش داده می شه.
وقتی اونو داخل SP اجرا می کنم حدود 8 دقیقه طول کشید.

in_chand_nafar
چهارشنبه 19 تیر 1392, 14:58 عصر
دوست عزيز بهتر است Actual Execution Plan كوئري رو قرار دهيد. روي Toolbar اين گزينه رو كليك و كوئري رو اجرا كنيد بع Plan رو ذخيره كنيد
در ضمن براي استفاده از Dynamic SQL بهتر كوئري رو در سورس درست كنيد سپس پارامترهاي اون (قسمت Where) را تر و تميز كرده و از طريق سورس دستو Sp_ExecuteSQL را فراخواني كنيد تمامي ORMها مثل EF,NH,... اين كار را انجام مي دهند
اين هم نمونه استفاده از آن
http://msdn.microsoft.com/en-us/library/aa933299(v=sql.80).aspx
http://stackoverflow.com/questions/462312/executing-stored-procedure-via-sp-executesql
http://oakdome.com/programming/SQL_DynamicSQL_sp_executesql.php

resident
چهارشنبه 19 تیر 1392, 23:59 عصر
اینم از Actual Execution Plan :)

in_chand_nafar
پنج شنبه 20 تیر 1392, 10:58 صبح
اگر توي Plan تون دقت كنيد بيشتيرن Cost شما مربوط به Sort است كه اون هم مربوط به Row_number است كه در اون فيلد personid بايد مرتب بشه
مي توانيد با ايندكس مناسب و ... اون رو حل كنيد اون حجم سنگين ديتا بر اساس personid بايد مرتب و چند ركورد مورد نظر شما نشون داده بشن
اگر نوع مرتب سازي رو بر حسب كليد اصلي جدول بزرگتون بگذاريد شايد مشكل رفع شود (البته اين موضوع نيازمند بررسي و... است)
در كل در كوئري تون بهتر است از * هم استفاده نكنيد چون * باعث مي شود كه Selectivity ايندكس ها پايين بيايد هر فيلدي كه لازم داريد در Select بياوريد