PDA

View Full Version : Index Tuning



محمد سلیم آبادی
جمعه 24 اردیبهشت 1389, 06:39 صبح
سلام،
این مطلب (http://pratchev.blogspot.com/2007/04/pivoting-data-in-sql-server.html)را راجب Pivoting Data از Plamen Ratchev خواندم ولی مقاله بحث Query Tuning را پوشش نداده بود.
و چندتا Comment هم گذاشتم ولی جواب درست حسابی دریافت نکردم.


اگر ستونی که با آن داده ها را فیلتر می کنیم داخل یک عبارت استفاده شود ایندکس مربوط به آن استفاده نخواهد شد و جدول به جای Index Seek اسکن خواهد شد.
مثلا عبارات:

LEFT(name, 1)='A' --d
CONVERT(integer, i) > 5000 --d
YEAR(date) ='2010' --d
DATEPART(yyyy, date)='2005'--d

حالا سوالم این هست که نباید با کمک ستون های محاسباتی این مقادیر را ذخیره کنیم و روی آنها شاخص بگذاریم تا index استفاده شود؟

از طرفی در بحث Pivoting با روش CASE اگر بخواهیم آمار ماه اول، دوم و سوم را بدست آوریم می تونیم قبل از گروه بندی، سطرها های مورد نظر را فیلتر کنیم تا تمام داده های جدول (که طبعا به آنها احتیاج نداریم) خواندن نشن. به شکل زیر توجه کنید (می تونید کد مربوط به CASE را از مقاله مشاهده کنید)


SELECT ... FROM table
WHERE month >=1 AND month <=3


ولی اگر بخواهیم آمار ماه اول و ماه پنجم را بدست آوریم ناچاریم این دستور را بنویسیم:


WHERE month = 1 OR month = 5


اگر روی ستون month یک Nonclustered ایندس تعریف کرده باشیم بگونه ای که تمام ستون های مورد نیاز جدول (چه ستون هایی که در target لیست شدن و چه در group by استفاده شدن) را پوشش داده باشد، از آن استفاده خواهد شد؟


در کل من روش CASE برای حل مساله ی Cross tabbing را نسبت به روش Multiple outer join جالب نمی بینم. درسته که در روش CASE داده های جدول تنها یک بار read میشن ولی این روش در مقابل روش outer join که از ایندکس به شکل بهینه استفاده می کند سرعت کمتری دارد. (این رو نتیجه ی آزمایش مشخص کرده)


با تشکر،

AminSobati
دوشنبه 27 اردیبهشت 1389, 15:00 عصر
سلام دوست عزیزم،
متاسفانه فرصت مطالعه لینک پیدا نشد ولی متوجه سوال شما شدم.

- در خصوص سوال اول: اعمال کردن تابع روی فیلدی که مورد جستجو هست، دقیقا باعث Scan میشه و دیگه Searchable Argument به حساب نمیاد. در بعضی شرایط میشه با ترفندهایی از تابع خلاص شد. مثلا به جای:

WHERE YEAR(OrderDate)=2000

بنویسیم

WHERE OrderDate BETWEEN '2000-1-1' and '2000-12-31'

اما در بعضی حالتها ترفندی پیدا نمیشه و ناچار هستیم از تابع استفاده کنیم. همونطور که اشاره کردید، اضافه کردن یک Computed Column و ساخت ایندکس روی اون، میتونه Index Seek رو تامین کنه

- سوال دوم: در حالتهای زیادی، استفاده از OR باعث Scan میشه. مگر حالتهای ساده که Query Processor میتونه با index intersection دو Seek جداگانه انجام بده. راجع به Cross-Tab Report، تا وقتی که Plan کوئری رو ندیدیم، نمیشه نظر قطعی داد و ایندکس مناسب رو پیشنهاد کرد

محمد سلیم آبادی
دوشنبه 27 اردیبهشت 1389, 15:13 عصر
تشکر،
این مطالبی را که عنوان کردین دقیقا در کتاب MCTS گفته شده. مثل اون تکنیک. ولی در سناریوی موجود از این تکنیک نمیشه استفاده کرد. ما نیاز داریم بر اساس سال (که از تاریخ محاسبه میشه) گروه بندی کنیم. یا فیلتر را روی ماه (از داده ی تاریخ) انجام بدیم در اینصورت این عبارات به عنوان SARG در نظر گرفته نمیشن.

به هر حال ممنون از پاسختون، امید وارم در آینده بیشتر فرصت پیدا کنید :چشمک: