ورود

View Full Version : سوال: اجرای طولانی مدت کوئری



hamidnet
جمعه 02 بهمن 1388, 17:37 عصر
سلام.
کوئری زیر دقیقا 6 ثانیه زمان می بره و فقط 1230 رکورد برمی گردونه که برای این مقدار رکورد زمان خیلی زیادیه.
ایندکس گذاری هم فایده ای نداره چون تمامی فیلدها باید بازیابی بشن.
از دوستان و اساتید محترم تقاضا دارم راهنماییم کنید.
متشکرم.


SELECT Movies.Id AS id, COUNT(*) AS CountBuy, Movies.SubtitleText as subtext,
Movies.Fname, Movies.CreateDate, Movies.Director, Movies.Abstract, Movies.IMDB, Movies.Parts,
Movies.Price, Movies.Photo, Movies.AdddateEn, Categories.CatName,
CONVERT(nvarchar, Movies.Subtitle) AS sub ,
Categories.CatName + ' (' +MainCategories.CatName+')' AS MainCatName
FROM BagMovie AS BagMovie_1 INNER JOIN Movies ON
BagMovie_1.MovieId = Movies.Id INNER JOIN Categories ON
Movies.CatId = Categories.Id INNER JOIN MainCategories ON
Categories.MCatId = MainCategories.Id GROUP BY
Movies.Id, Movies.Fname,Movies.SubtitleText, Movies.CreateDate, Movies.Director, Movies.Abstract,
Movies.IMDB, Movies.Parts, Movies.Price, Movies.Photo, Movies.AdddateEn, Categories.CatName,
Convert(nvarchar, Movies.Subtitle),Convert(nvarchar, Movies.ShowInFirstPage),
MainCategories.CatName Having Convert(nvarchar, Movies.ShowInFirstPage)='1' UNION SELECT '~/bag.jpg' as img,
Movies_1.Id AS id, 0 AS CountBuy, Movies_1.SubtitleText as subtext,Movies_1.Fname, Movies_1.CreateDate, Movies_1.Director,
Movies_1.Abstract, Movies_1.IMDB, Movies_1.Parts, Movies_1.Price, Movies_1.Photo, Movies_1.AdddateEn, Categories_1.CatName,
CONVERT(nvarchar, Movies_1.Subtitle) AS sub , Categories_1.CatName + ' (' +MainCategories_1.CatName+')' AS MainCatName
FROM Movies AS Movies_1 INNER JOIN Categories AS Categories_1 ON Movies_1.CatId = Categories_1.Id INNER JOIN
MainCategories AS MainCategories_1 ON Categories_1.MCatId = MainCategories_1.Id
WHERE (Movies_1.Id NOT IN ( SELECT MovieId FROM BagMovie)) and
Convert(nvarchar, Movies_1.ShowInFirstPage)='1' order by Movies.Id DESC

AminSobati
یک شنبه 04 بهمن 1388, 20:33 عصر
Execution Plan مورد نیازه!

محمد سلیم آبادی
یک شنبه 04 بهمن 1388, 20:54 عصر
سلام،
زمانی که query مورد نظر غیر ممکن است که اجرا شود Plan چه کاربردی دارد؟!
result-query_1 پانزده ستون برمی گرداند و result_query_2 شازنده ستون ممکنه با استفاده از union این دو result ترکیب شوند؟!

AminSobati
یک شنبه 04 بهمن 1388, 22:43 عصر
مسلما مشکل 15 یا 16 فیلد برطرف میشه، شاید اشکال در پست کردن Query بوده. اما چیزی که در بدو امر جلب توجه میکنه، استفاده از تابع (مثل Convert) روی فیلدها هست که باعث میشه Index استفاه نشه و Scan اتفاق بیافته

محمد سلیم آبادی
یک شنبه 04 بهمن 1388, 22:58 عصر
با نگاه گذرا به query به نظر میرسد با کمک یک derived table بتوان query_1 را بهینه تر کرد به این معنا که نیازی نباشد در grouping set تمام ستون ها قرار گیرند. و احتمال اینکه بتوان به شکل بهینه تری query را خلق کرد وجود دارد (البته با شناخت صورت مساله)

از طرفی بدلیل استفاده از تابع convert در دو ماده ی select و group by هزینه ی دو عملگرهای Hash Match و Compute Scalar به هزینه های query اضافه خواهد شد.

hamidnet
سه شنبه 06 بهمن 1388, 01:34 صبح
از مدیران محترم متشکرم.
باید بگم یه تک فیلد جا موند!!
کوئری اجرا میشه در 6 ثانیه!!
دو جدول بیش از هزار رکورد و یکی بیش از 26 هزار رکورد داره.
گفته شد تابع convert هزینه بر هست. اگر واقعا هزینه زمانی زیادی داره میشه نوع فیلد رو عوض کرد تا نیاز به تبدیل نباشه.
نمودار Execution Plan رو برای دوستان محترم میزارم تا اگر زحمتی نیست یه نگاه بهش بندازنید.

AminSobati
سه شنبه 06 بهمن 1388, 02:46 صبح
تابع Convert رو از روی فیلد ShowInFirstPage در جدول Movies حذف کنید. یعنی جایی که گفته شده:
CONVERT(nvarchar(30),[filmresan].[dbo].[Movies].[ShowInFirstPage],0)=N'1'

حالا دوباره Query رو اجرا و Plan رو ارسال کنید

hamidnet
سه شنبه 06 بهمن 1388, 13:50 عصر
با تشکر فراوان.
تمامی convert ها رو حذف کردم و لی باز هم مدت زمان اجرا همان 6 ثانیه هست.
پلن رو هم براتون فرستادم.

(خارج از هرگونه تعریف و تمجید بی جا!! واقعا ازتون ممنونم که اینقدر خوب و با حوصله با سوالات جواب میدید. )


SELECT '~/bag.jpg' as img,Movies.Id AS id, COUNT(*) AS CountBuy, Movies.SubtitleText as subtext,
Movies.Fname, Movies.CreateDate, Movies.Director, Movies.Abstract, Movies.IMDB, Movies.Parts,
Movies.Price, Movies.Photo, Movies.AdddateEn, Categories.CatName,
Categories.CatName + ' (' +MainCategories.CatName+')' AS MainCatName
FROM BagMovie AS BagMovie_1 INNER JOIN Movies ON
BagMovie_1.MovieId = Movies.Id INNER JOIN Categories ON
Movies.CatId = Categories.Id INNER JOIN MainCategories ON
Categories.MCatId = MainCategories.Id GROUP BY
Movies.Id, Movies.Fname,Movies.SubtitleText, Movies.CreateDate, Movies.Director, Movies.Abstract,
Movies.IMDB, Movies.Parts, Movies.Price, Movies.Photo, Movies.AdddateEn, Categories.CatName,
MainCategories.CatName UNION SELECT '~/bag.jpg' as img,
Movies_1.Id AS id, 0 AS CountBuy, Movies_1.SubtitleText as subtext,Movies_1.Fname, Movies_1.CreateDate, Movies_1.Director,
Movies_1.Abstract, Movies_1.IMDB, Movies_1.Parts, Movies_1.Price, Movies_1.Photo, Movies_1.AdddateEn, Categories_1.CatName,
Categories_1.CatName + ' (' +MainCategories_1.CatName+')' AS MainCatName
FROM Movies AS Movies_1 INNER JOIN Categories AS Categories_1 ON Movies_1.CatId = Categories_1.Id INNER JOIN
MainCategories AS MainCategories_1 ON Categories_1.MCatId = MainCategories_1.Id
WHERE (Movies_1.Id NOT IN ( SELECT MovieId FROM BagMovie)) order by Movies.Id DESC

AminSobati
سه شنبه 06 بهمن 1388, 14:43 عصر
سلام،
قائدتا این سه ایندکس باید تاثیر خوبی داشته باشه:



create index ix1 on BagMovie (MovieId)

create index ix1 on Movies(CatId,Id)
include (Fname, CreateDate, Director, Abstract, IMDB, Parts, Price, Photo, AdddateEn, SubtitleText )

create index ix1 on MainCategories (id) include(catname)

hamidnet
سه شنبه 06 بهمن 1388, 19:06 عصر
آقا خیلی ممنون.
شد یک ثانیه.
خیلی لطف کردی.