نقشه اجرای کوئری
  نقشه گرافیکی اجرای یک کوئری یا بطور خلاصه Plan به منظور بررسی چگونگی اجرا شدن کوئری توسط کامپیوتر می پردازد.
   SQL Server
   ۱۹۷۲۱
   این مقاله حاوی فایل ضمیمه نمی باشد
   محمد سلیم آبادی
   ۱۳۸۹/۱۰/۲۵
ارسال لینک صفحه برای دوستان ارسال لینک صفحه برای دوستان  اضافه کردن به علاقه مندیها اضافه کردن به علاقه مندیها   نسخه قابل چاپ نسخه قابل چاپ

 

مقدمه

در این مقاله سعی شده است Query Execution Plan بطور خلاصه معرفی شود. این ابزار در برنامه ی Microsoft SQL Server Managment Studio یا بطور خلاصه SSMS قابل بکارگیری و مشاهده است. از آنجایی که کمتر برنامه نویسی از این ابزار و قابلیت برای بهینه کردن کوئری ها استفاده می کند تصمیم گرفتم در یک مقاله مختصر و مفید در پی معرفی این ویژگی در عمل بپردازم و کمک کنم به برنامه نویسانی که می خواهند کمی عمیق تر و با معلومات بیشتری این راه را ادامه بدهند. نقشه (plan) را از چند طریق می توان مشاهده کرد که در ادامه به آنها اشاره کرده ام، نوع گرافیکی آن برای شروع مناسب تر است بر همین اساس در مقاله به نوع گرافیکی پرداختیم.

نقشه ی اجرای پرس و جو (Query Exceution Plan)

query graphical execution plan یا بطور خلاصه plan ابزار و قابلیتی است که به ما می گوید کوئری چگونه اجرا خواهد شد (یا اینکه چگونه اجرا شده است). با کمک این نقشه می توانیم تیکه کد SQL که باعث افت عملکردی شده است را پیدا کنیم و اصلاحش کنیم. بطور مثال آیا کوئری تمام داده های جدول را Scan کرده است یا اینکه از یک Index مناسب برای استخراج داده های مورد نظر استفاده کرده است.

قبل از هرچیزی باید بدانید که نقشه (Plan) را از چند طریق می توانیم مشاهده کنیم؛ از سه طریق: عناصر گرافیکی (Graphical)، متنی و XML. و دو نوع نقشه وجود دارد: واقعی (Actual) که کوئری را اجرا می کند و سپس، نشان می دهد که هنگام اجرای کوئری واقعا چه اتفاق هایی رخ داده است و دیگری تخمین زده شده یا Estimated که نمایان گر خروجی Optimizer (بهینه کننده) است و نیازی به اجرای کوئری ندارد. Optimizer یک تکه نرم افزاری است که بر اساس یکسری آمار و ارقام یک راه بهینه برای اجرای یک کوئری را ایجاد میکند. هر کوئری که ما Submit می کنیم توسط Optimizer بطور اتوماتیک بهینه می شود.

نمایش نقشه

برای پیاده سازی و ارائه مطالب از بانک Northwind استفاده شده. اگر این بانک را در سیستم خود ندارید و در نتیجه Attach نکردین توصیه می شود آن را دریافت و Attach کرده تا همزمان با مطالعه مقاله عملا نیز مطالب را تجربه کنید.
از کوئری زیر در طول مقاله استفاده کرده ام که می توانید آن را در
SSMS خود Copy و Paste کنید:

SELECT [CustomerID], [CompanyName], [City], [Region]
FROM [Northwind].[dbo].[Customers]
WHERE [Country] = 'Germany'
ORDER BY [CompanyName]

برای آوردن نقشه از چهار طریق اینکار صورت می گیرد: کلید میانبر (shortcuts)، منوی Query، میله ابزار(tool bar) و پنجره Pop-up (پنجره ای که با راست کلیک کردن روی کوئری باز می شود). در تصویر زیر دو دکمه مذکور در میله ابزار در کادر نارنجی قابل مشاهده است.
در تصویر زیر هر دو ابزار
Actual و Estimated قابل مشاهده است. در صورتی که این ابزارها قابل رویت نبود کافیست از ابزارها گزینه SQL Editor را انتخاب کنید. برای مشاهده کلید های میانبر این دو ابزار می توانید با کمک منوی Query اینکار را انجام دهید. که Ctrl+L برای "تخمین زده شده" و  Ctrl+M برای "واقعی" مورد استفاده قرار می گیرد.

دکمه Include Actual Execution Plan بگونه ای است که خاموش و روشن می شود اگر روشن باشد و کلیک کنیم خاموش و اگر خاموش بوده روشن می شود. و زمانی که کوئری اجرا شد آن نیز می آید. ولی دکمه Display Estimated Execution Plan را اگر فشار دهیم نقشه تخمین زده شده نمایان می شود.

 

بعد از فشار دکمه Display Estimated Execution Plan خواهیم دید:

 


در این پنجره (Execution Plan) شما قادر هستید که عمل بزرگ نمایی (Zoom) را توسط راست کلیک روی یک قسمت خالی از صفحه باز شده انجام دهید. با عمل راست کلیک pop-up زیر باز خواهد شد:


گزینه اول برای ذخیره کردن، دوم برای نمایش فرم XML و سوم یعنی Zoom In برای بزرگنمایی... و Zoom to Fit برای بزرگنمایی به گونه ای که کل صفحه مانیتور را پوشش دهد استفاده می شوند.

طریقه خواندن نقشه

نقشه گرافیکی از یکسری آیکن ها (عملوند/operator) همراه با جهت ها که جریان (flow) نقشه را نشان می دهند تشکیل شده است. جهت خواندن آن از راست به چپ (right to left) و از بالا به پایین (top to bottom) است. از طریق این نقشه ما می توانیم بفهمیم در هر مرحله چه تعداد سطر برگشته یا فیلتر شده و کدام عمل (عملگر) بیشترین هزینه را به کامپیوتر متحمل کرده. مثلا عمل مرتب سازی (Sort) هفتاد درصد هزینه اجرای کوئری را در بر گرفته. برای مشاهده درصد هزینه هر عملگر کافیست به قسمت Cost زیر هر آیکن دقت کنید.

یکی از موارد استفاده ی نقشه گرافیکی، مقایسه چند کوئری است که نتایج یکسان را می دهند ولی از شیوه های متفاوتی نوشته شده اند. برای این منظور کافیست دو یا چند کوئری را در یک پنجره قرار دهید و اجرایشان کنید در سر برگ Execution plan درصد هزینه هر کوئری در بالای هر قسمت نمایش داده می شود. بطور مثال چون که ما یک کوئری تنها را اجرا کردیم، کوئری تمام هزینه یعنی 100 درصد را به خود اختصاص داده است (به قسمت Query 1 : Query Cost توجه کنید).

هر یک از عملوند ها و جهت ها حاوی یکسری اطلاعات هستند که با مکس کوتاهی روی آنها tool-tip ای ظاهر می شود. در ادامه خلاصه ای از اطلاعات که tool tip نشان می دهد را برای تک تک آیکن ها و فلش ها شرح می دهم.


_________________________________________________________________________________

1: عملگر Clustered Index Scan


اگر نقشه از نوع Actual بود Actual Number of Rows نیز بعد از Physical Operation نشان داده می شد. که نشان دهنده تعداد سطر واقعی است.

  • Physical Operation: عملگر فیزیکی برای این بخش از Plan، مثل Seek، Join، Scan و ...

  • Logical Operator: عملگر منطقی این بخش از Plan

  • Estimated Operator Cost: این جمع مقادیر دو پارامتر Estimated CPU cost و Estimated I/O cost است. در واقعا هزینه هر عملگر به درصد که پایین آیکن هر عملگر دیده می شود به این مقدار اشاره می کند. برای محاسبه این درصد کافیست مقدار Estimated Subtree Cost موجود در tooltip عملگر SELECT را بدست آورده و عدد 100 را تقسیم بر این عدد کرده و مقدار Estimated Operator Cost را ضرب در این عدد کنیم تا درصد بدست آید. برای تمرین با کمک مقادیر همین پلن می توانیم درصد را محاسبه کنیم. عدد 163 جمع کل هزینه ها، 114 هزینه عملگر sort و 48 هزینه عملگر Scan. حالا 100 را تقسیم به 163 کرده و ضرب در 114 می کنیم که عددی نزدیک به 70 بدست می آید...

  • Estimated Subtree Cost: مجموعه هزینه ی عملگرهای قبلی تا این عملگر. توجه داشته باشید که اجرای عملگر ها از راست به چپ است.

  • Estimated Number of Rows: تعداد سطر های تخمین زده شده بر اساس آماری که در بهینه کننده کوئری (Query Optimizer) موجود است.

_________________________________________________________________________________

2.جهت جریان داده: از Scan به Sort


بسادگی از روی این tooltip می توانیم بفهمیم که نقشه گرافیکی از نوع Estimated است یا Actual. در نوع Actual مقدار Actual Number Of Rows نیز وجود دارد. اعداد این مرحله مقادیر هستند که تا قبل از عملگر بعدی موجود بودند. و توسط عملگر بعدی مورد تغییر (مثل فیلتر شدن) قرار می گیرند.


_________________________________________________________________________________

3. عملگر Sort

tooltip این مرحله نیز شبیه به عملگر Scan است ولی بدهیهی است که مقادیر متفاوت اند.

4.جهت جریان داده: Sort به SELECT

این نیز دقیقا مشابه مورد 2 است.

5. عملگر SELECT

آیتم جدیدی که در tooltip این عملگلر وجود دارد Catched Plan Size است که مقدار حافظه ای که به این نقشه کوئری جهت عمل Catch اختصاص داده شده است.

نتیجه گیری

با مطالعه این مقاله بسیار ساده متوجه ابزار بسیار جالبی شدیم که به ما کمک می کند تا بفهمیم کوئری ما دقیقا از چه روشی اجرا شده است و کدام قسمت از کوئری باعث افت عملکردی شده است و مثلا هنگامی که نیاز به استخراج زیر مجموعه ای از سطرهای جدول است آیا تمام جدول خوانده شده است یا اینکه از روی Index داده های مورد نظر بسرعت بدست آمده اند.

با خواندن این مقاله یاد گرفتیم که چگونه چند کوئری که نتیجه یکسان دارند را با همدیگر مقایسه کنیم تا متوجه شویم کدام یک هزینه کمتری دارند و نیاز به منابع سخت افزاری کمتری برای اجرا شدن دارند.
در پایان امید وارم این مقاله توانسته باشد شما را با این قابلیت در حد معرفی آشنا کرده باشد.