در این مقاله عملگرد SQL Server در اجرای کوئری پرکاربرد زیر توضیح داده می شود.
[sql] SELECT COUNT (*) FROM mytable [/sql]
|
یک سوال در مورد کوئری بالا می تواند این باشد که آیا SQL Server همیشه برای بدست آوردن تعداد رکوردها از table scan استفاده می کند یا خیر؟
جواب خیر است. Query Processor از ایندکس با حداقل تعداد page برای شمارش استفاده می کند تا I/O کمتری زده شود.
اجازه دهید این موضوع را آزمایش کنیم.
[sql] CREATE TABLE CTest (c1 INT IDENTITY, c2 BIGINT DEFAULT 1, c3 CHAR (1000) DEFAULT ‘a’);
GO
SET NOCOUNT ON;
GO
INSERT INTO CTest DEFAULT VALUES;
GO 10000 [/sql]
|
قبل از اجراین کوئری دکمه Include Actual Query Plan را غیر فعال کنید:
در غیر اینصورت 10000 پلن گرافیکی در SSMS تولید می شود و پیام زیر صادر می شود:
The query has exceeded the maximum number of result sets that can be displayed in the Execution Plan pane. Only the first 250 result sets are displayed in the Execution Plan pane.
حالا اگر SELECT COUNT(*) بگیریم، پلن حاصل به این شکل خواهد بود:
Query Processor راهی جز انتخاب Table Scan ندارد. حالا من یک ایندکس Nonclustered اضافه می کنم که دارای page های کمتری نسبت به خود جدول است:
[sql] CREATE NONCLUSTERED INDEX CTest_1 ON CTest (c2);
GO [/sql]
|
و پلن SELECT به شکل زیر است:
توجه کنید که عملگر table scan به Index Scan روی ایندکس CTest_1 تغییر کرده است. به دلیل اینکه ایندکس دارای Page های کمتری نسبت به جدول است و بنابراین هزینه I/O کمتر است.
حالا من یک ایندکس ایجا می کنم که از ایندکس CTest_1 هم کوچکتر است، یعنی روی ستونی با دیتاتایپ integer:
[sql] CREATE NONCLUSTERED INDEX CTest_2 ON CTest (c1);
GO [/sql]
|
و دوباره پلن به پلن با ایندکس کوچکتر تغییر می کند:
و همانطوری که انتظارش را داشتم دوباره تغییر کرد.
حالا اجازه دهید به تعداد page های هر ایندکس نگاهی بیندازیم:
[sql] SELECT [index_id], [page_count]
FROM sys.dm_db_index_physical_stats (DB_ID (), OBJECT_ID (‘CTest’), NULL, NULL, ‘LIMITED’);
GO
index_id page_count
———– ——————–
0 1436
2 28
3 19 [/sql]
|
هر باری که Query Processor اقدام به انتخاب یک ایندکس می کند یکی از عواملی که در انتخابش دخیل است هزینه I/O است.
و به یاد داشته باشید که کوچکرین ایندکس برای این منظور ایجاد ایندکس Nonclustered روی ستونی است که روی آن ایندکس Clustered ایجاد شده و البته موارد کارایی آن هم به مراتب کمتر از سایر ایندکس ها خواهد بود.
امیدوارم مفید بوده باشد.
هیچوقت به داشتن سرکارگر عادت نکن
نوامبر 2015، تورج عزیزی
8 دیدگاه
مجتبی شهریور
سلام
بسیار عالی و کاربردی بود
متشکرم
روزبه هدایت نیا
درود بر تورج
سید محمد حسینی
با سلام
مسعود طاهری
سلام
تورج عزیزی
سلام
فرشید علی اکبری
سلام
مسعود طاهری
این نوع ایندکس ها برای تست و آزمایش ساخته می شود تا در صورتیکه مفید واقع بود بتوان از آن در پروژه استفاده کرد.
داود وحدانی
عالی بود