خانه / مقالات / بانک های اطلاعاتی / بهینه سازی پرس و جوی SQL Server

بهینه سازی پرس و جوی SQL Server

بهینه سازی پرس و جوی SQL Server
هنگام بهینه سازی پرس و جو، بهینه ساز از تخمین های کاردینالیتی برای عملیاتی همچون فیلترها، پیوندها، گروهبندی و غیره استفاده می کند تا برای انتخاب خود از میان استراتژی های پردازش موجود از آنها کمک بگیرد. وقتی ورودی های کاربر شناخته شده هستند و آمار موجود می باشد، بهینه ساز می تواند بطور بالقوه تخمین های کاردینالیتی صحیح و در نتیجه انتخاب های مطلوب و بهینه را انجام دهد.
وقتی که آمار و ورودی های کاربر موجود نباشند، بهینه ساز متوسل به استفاده از یک تکنیک تخمین کاردینالیتی به نام optimize for unknown می شود. در چنین موردی، اگر این فرآیند را تخمین زدن یا estimating بنامیم، ممکن است کمی غلو آمیز باشد. این فرآیند بیشتر شبیه حدس زدن است تا تخمین زدن. اگر خوش شانس باشید، تخمین هایی را دریافت می کنید که تا حدودی به واقعیت نزدیکترند. اگر خوش شانس نباشید، تخمین های نادرستی را دریافت می کنید که می تواند منجر به انتخاب های نه چندان مطلوب شود.
در این مقاله، حدس و گمان های hard-code شده را ارائه می دهیم که بهینه ساز همراه با تکنیک optimize for unknown استفاده می کند، در این صورت حداقل می فهمید که بهینه ساز حدس می زند چه چیزی را نمی داند. تنظیم یک پرس و جوی خوب، تا حد زیادی با توانایی در توضیح تخمین های کار دینالیتی آغاز می شود، بخصوص تخمین هایی که صحیح نیستند.
در مثال هایی که عنوان می کنیم، جدول Sales.SalesOrderDetail را در پایگاه اطلاعاتی نمونه AdventureWorks2014 پرس و جو می کنیم. همچنین باید مطمئن شوید که پایگاه اطلاعتی روی مد سازگاری ۱۲۰ تنظیم باشد تا اطمینان حاصل شود که SQL server از تخمین زننده ی کاردینالیتی جدید بطور پیش فرض استفاده می کند. برای این کار میتوانید کد زیر را اجرا کنید:

— Make sure db compatability is >= 120 to use new CE by default
USE AdventureWorks2014; — https://msftdbprodsamples.codeplex.com/releases/view/125550
GO

IF ( SELECT compatibility_level
FROM sys.databases
WHERE name = N’AdventureWorks2014′ ) < 120

ALTER DATABASE AdventureWorks2014
SET COMPATIBILITY_LEVEL = 120; — use 130 on 2016

ما از طریق اپراتورهای زیر تخمین های optimize for unknown را تجزیه کردیم:
• >, >=, <, <=
• BETWEEN and LIKE
=
در بخش اول جایی که اولین گروه اپراتورها را عنوان می کنیم، تفاوت سناریوهایی را که در آن بهینه ساز از تکنیک optimize-for-unknown استفاده می کند را نمایش می دهیم. در بخش های بعدی فقط از یک یا چند سناریو برای نشان دادن تخمین ها استفاده می کنیم.
تخمین های optimize for unknown برای اپراتورهای : >, >=, <, <=
تخمین optimize-for-unknown برای گروهی از اپراتورهای >, >=, <و<= 30 درصد کاردینالیتی ورودی است.
مثلاً فرض کنید که شما جدول Sales.SalesOrderDetail را در پایگاه اطلاعاتی AdventureWorks2014 پرس و جو می کنید و از فیلتری مانند WHERE OrderQty.=<unknown_input> استفاده می کنید. کار دینالیتی جدول ۱۲۱۳۱۷ سطر است بنابراین تخمین کاردینالیتی فیلتر ۰٫۳*۱۲۱۳۱۷=۳۶۳۹۵٫۱ خواهد بود. اینکه آیا این عدد نزدیک به عدد واقعی سطرهایی است که شما در موارد معمولی دریافت می کنید، مربوط به خودتان می شود اما این همان چیزی است که بهینه ساز فرض می کند.
از آنجائیکه این اولین بخشی است که در آن تکنیک optimize for unknown را نشان می دهیم، بگذارید با لیست کردن موارد مختلفی آغاز کنیم که این تکنیک همراه با مثال های قابل اجرا استفاده می شود.
مواردی که تکنیک optimize for unknown استفاده می شود:
۱- هنگام استفاده از متغیرهای محلی.
برخلاف مقادیر پارامتری که قابل اسنیف هستند، مقادیر متغیر معمولا قابل اسنیف نیستند. دلیل آن ساده است: واحد بهینه سازی اولیه، کل batch است- نه فقط عبارت پرس و جو. متغیرها معرفی می شوند و با مقادیر به صورت بخشی از batch ای که بهینه سازی شده است، تعیین می گردند. لحظه ای که پرس و جو بهینه سازی می شود قبل از تعیین متغیرهاست و بنابراین مقادیر متغیر قابل اسنیف نیستند. نتیجه این است که بهینه ساز باید متوسل به استفاده از تکنیک optimize for unknown شود.
برای مقایسه تکنیک optimize-for-unknown با تکنیک optimize for known ، پرس و جوی زیر را در نظر بگیرید که دارای یک گزاره فیلتر با اپراتور >= و یک ثابت شناخته شده به عنوان ورودی است:

SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty >= 40

GROUP BY ProductID;

طرح اجرایی که از این پرس و جو دریافت کردیم در شکل ۱ می بینید.
شکل۱: طرح پرس و جوی مربوط به پرس و جو با یک ثابت

در اینجا ابزار قدیمی که بهینه ساز با آن تخمین کاردینالیتی مربوط به فیلتر را انجام می دهد، یک هیستوگرام است. اگر قبل از اجرای این پرس و جو در ستون OrderQTY ، هیستوگرام وجود نداشته باشد و شما ساخت خودکار آمارها در پایگاه اطلاعاتی را غیرفعال نکرده باشید، SQL Server وقتی پرس و جو را اجرا کردید، یک هیستوگرام می سازد. شما میتوانید از پرس و جوی لیست ۱ استفاده کنید تا نام آماری که بطور خودکار ساخته می شود را دریافت نمایید.
لیست۱: شناسایی آماری که بطور خودکار در ستون OrderQty ساخته می شوند

SELECT S.name AS stats_name

FROM sys.stats AS S

INNER JOIN sys.stats_columns AS SC

ON S.object_id = SC.object_id

AND S.stats_id = SC.stats_id

INNER JOIN sys.columns AS C

ON SC.object_id = C.object_id

AND SC.column_id = C.column_id

WHERE S.object_id = OBJECT_ID(N’Sales.SalesOrderDetail’)

AND auto_created = 1

AND C.name = N’OrderQty’;

وقتی این کد را پس از اجرای پرس و جوی قبلی اجرا کردیم؛ نام آماری WA-Sys-00000004-44CA3770 را دریافت کردیم. شما نامی را که دریافت می کنید، یادداشت نمایید. پس از جایگزین کردن نام آمار مورد نظرتان با نامی که دریافت کرده اید، از کد زیر استفاده کنید تا هیستوگرام را ببینید:

DBCC SHOW_STATISTICS (N’Sales.SalesOrderDetail’, N’_WA_Sys_00000004_44CA3770′)

WITH HISTOGRAM;
در جدول ۱، چند مرحله آخر در هیستوگرام را می بینید.

جدول ۱ : آخرین مراحل هیستوگرام
RANGE_HI_KEY RANGE_ROWS EQ_ROWS DISTINCT_RANGE_ROWS AVG_RANGE_ROWS
———— ————- ————- ——————– ————–

۳۸ ۰ ۱ ۰ ۱
۳۹ ۰ ۱ ۰ ۱
۴۰ ۰ ۲٫۰۰۶۳۹۲ ۰ ۱
۴۱ ۰ ۱ ۰ ۱
۴۴ ۰ ۱ ۰ ۱

به وضوح می بینید که تخمین کار دینالیتی به نمایش درآمده در شکل ۱ وابسته به ۳ مرحله آخر هیستوگرام است. این تخمین کاملاً درست است: ۴٫۰۰۶۳۹ در مقابل واقعیت ۴٫
در مقابل مثال بالا، پرس و جوی زیر از یک متغیر محلی استفاده می کند و بهینه ساز را مجبور به استفاده از تکنیک “optimize for unknown” می نماید.

DECLARE @Qty AS INT = 40;
SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty >= @Qty

GROUP BY ProductID;

طرح مربوط به این پرس و جو در شکل ۲ نشان داده شده است:

شکل ۲: طرح پرس و جو زمانی که از اپراتور >= با یک متغیر استفاده می شود

همانطور که پیش بینی می کردیم، تخمین، ۳۰ درصد کاردینالیتی وروردی است. جالب است عنوان کنیم که به دلیل تخمین نادرست کاردینالیتی، بهینه ساز استراتژی تجمع نه چندان مطلوب را انتخاب کرد. بهینه ساز استفاده از الگوریتم تجمع Hash Match را به جای الگوریتم Sort و Stream Aggregate انتخاب کرد. این فقط یکی از چند نتیجه احتمالی است که ممکن است ثمره تخمین های کاردینالیتی نادرست باشد.
استثنایی وجود دارد که در آن بهینه ساز قادر به اجرای اسنیفینگ متغیر می باشد، آن هم زمانی است که یک رویداد کامپایل در سطح دستور رخ می دهد. زیرا طبق تعریف، کامپایل در سطح دستور، بعد از هرگونه تعیین متغیر که قبلاً صورت گرفته بود، رخ می دهد. ریکامپایل های اتوماتیک همیشه در سطح دستور اتفاق می افتند. از زمان SQL Server 2005 تا به امروز همیشه به همین صورت بوده است. برای دریافت ریکامپایل دستی در سطح دستور، باید hint پرس و جوی RECOMPILE را با استفاده از عبارت OPTION بیافزائید به این صورت:

DECLARE @Qty AS INT = 40;
SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty >= @Qty

GROUP BY ProductID

OPTION (RECOMPILE);

این پرس و جو همان طرح شکل ۱ را میسازد، در حالیکه تخمین صحیح است.
توجه داشته باشید که اگر گزینه WITH RECOMPILE در سطح رویه را مشخص کنید، در اینصورت قادر به اسنیفینگ متغیر نخواهد بود. تنها hint پرس و جوی Option(RECOMPILE) این کار را انجام می دهد.
تکنیک optimize for unknown هم استفاده شده است.
۲- هنگامیکه که از پارامترها استفاده می کنید، اما با تعیین Optimize For Unknown یا Optimize For (@parameter UNKNOWN) یا با trace flag 4136، اقدام به غیرفعال کردن automatic parameter sniffing می نمایید.
مقادیر پارامتر بطور طبیعی قابل اسنیف هستند به همین دلیل است که قبل از آنکه batch جهت بهینه سازی به بهینه ساز انتقال داده شود، دراجرای رویه یا تابع، مقادیری را به آنها اختصاص می دهید. اگر می خواهید اسنیفینگ پارامتر برای تمام ورودیها غیر فعال شود، از hint ، OPTIMIZE FOR UNKNOWN استفاده کنید. اگر می خواهید اسنیفنگ یک پارامتر خاص را غیرفعال نمایید، از hint ، OPTIMIZE FOR (@parameter UNKNOWN) استفاده نمایید.
همچنین میتوانید از trace flag 4136 برای غیرفعال کردن اسنیفینگ پارامتر در گرانولیتی های مختلف استفاده نمائید: پرس و جو، جلسه ای یا همگانی. توجه کنید که هنگام استفاده از رویه ذخیره شده ای که به شکل بومی کامپایل شده، رفتار optimize for unknown پیش فرض می باشد.
به عنوان مثال، کد زیر یک رویه ذخیره شده می سازد و اسنیفینگ پارامتر را در پرس و جو با استفاده از hint ، OPTIMIZE FOR UNKNOWN غیر فعال می کند:

IF OBJECT_ID(N’dbo.Proc1′, N’P’) IS NOT NULL DROP PROC dbo.Proc1;

GO

CREATE PROC dbo.Proc1

@Qty AS INT

AS
SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty >= @Qty

GROUP BY ProductID

OPTION (OPTIMIZE FOR UNKNOWN);

GO

از کد زیر برای آزمایش رویه ذخیره شده استفاده نمائید:
EXEC dbo.Proc1 @Qty = 40;

ما طرح پرس و جویی شبیه طرح پرس و جوی تصویر ۲ دریافت کردیم که یک تخمین کار دینالیتی ۳۰درصد را نشان می دهد.
سناریوی دیگر برای وقتی که از تکنیک optimize for unknown استفاده می شود.
۳- وقتی آمار در دسترس نیستند.
موردی را در نظر بگیرید که هیچگونه هیستوگرامی در ستون فیلتر شده وجود ندارد و شما با غیرفعال کردن ساخت اتوماتیک آمار در سطح پایگاه اطلاعاتی و عدم ساخت شاخص در ستون، مانع از ساخت هیستوگرام توسط SQL Server می شوید. پس از جایگزین کردن نام آمار مورد نظر خود با نام آماری که از اجرای پرس و جوی قبلی (لیست ۱) دریافت کرده اید، از کد زیر برای مرتب کردن این محیط برای دموی خود استفاده نمایید:

ALTER DATABASE AdventureWorks2014 SET AUTO_CREATE_STATISTICS OFF;

GO

DROP STATISTICS Sales.SalesOrderDetail._WA_Sys_00000004_44CA3770;

سپس از کد زیر استفاده کنید که از یک ثابت در فیلتر استفاده می کند:

SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty >= 40

GROUP BY ProductID;

قبلاً که این پرس و جو را اجرا می کردید، طرح شکل ۱ را با یک تخمین کاردینالیتی صحیح دریافت می کردید، اما این بار از آنجائیکه بهینه ساز هیستوگرامی ندارد که به آن تکیه کند، از تکنیک optimize for unknown استفاده می کند و طرح به نمایش در آمده در شکل ۲ را با تخمین ۳۰ درصدی می سازد.
کد زیر را اجرا کنید تا ساخت خودکار آمار در پایگاه اطلاعاتی مجددا فعال شود:
ALTER DATABASE AdventureWorks2014 SET AUTO_CREATE_STATISTICS ON;

شما میتوانید پرس و جو را مجدداً اجرا نموده و ببینید که آیا طرح شکل ۱ را دریافت می کنید.
تخمین های optimize for unknown برای اپراتورهای BETWEEN و LIKE
هنگام استفاده از گزاره BEETWEEN، حدس hard-code شده بستگی به سناریو و تخمین زننده کار دینالیتی(CE)ای که استفاده می شود، دارد. CE به ارث مانده در تمام موراد از تخمین ۹درصدی استفاده می کند. پرس و جوی زیر این موضوع را ثابت می کند ( برای وادار کردن CE به انجام این کار از Query trace flag9481 استفاده شده است).

DECLARE @FromQty AS INT = 40, @ToQty AS INT = 41;
SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty BETWEEN @FromQty AND @ToQty

GROUP BY ProductID

OPTION(QUERYTRACEON 9481);
طرح مربوط به این پرس و جو در شکل ۳ به نمایش در آمده است. تخمین ۰٫۰۹ * ۱۲۱۳۱۷ = ۱۰۹۱۸٫۵
است.

شکل ۳ : طرح ای که تخمین ۹درصدی را نشان می دهد

CE جدید، هنگام استفاده از ثابت ها و هنگامیکه هیستوگرام وجود ندارد و هنگام استفاده از متغیرها یا پارامترها با اسنیفینگ غیرفعال از تخمین های مختلف استفاده می کند. در مورد قبلی از تخمین ۹ درصدی استفاده می کرد و در مورد دوم از تخمین ۱۶٫۴۳۱۷ درصدی استفاده می کند.
در اینجا مثالی داریم که کاربرد ثابت ها را نشان می دهد(حتما آمارهای موجود در ستون را حذف کنید و ساخت خودکار آمار را همانطور که قبلا نشان دادیم قبل از اجرای آزمایش غیر فعال و پس از آزمایش مجدا فعال نمائید).
DECLARE @FromQty AS INT = 40, @ToQty AS INT = 41;
SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty BETWEEN @FromQty AND @ToQty

GROUP BY ProductID

OPTION(QUERYTRACEON 9481);

ما همان طرح به نمایش درآمده در شکل ۳ را با تخمین ۹درصدی دریافت کردیم.
این مثالی است که استفاده از متغیرها را نشان می دهد (همان رفتاری که هنگام استفاده از پارامترها با اسنیفینگ غیرفعال شاهد آن هستیم)

DECLARE @FromQty AS INT = 40, @ToQty AS INT = 41;
SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty BETWEEN @FromQty AND @ToQty

GROUP BY ProductID;

ما طرح به نمایش درآمده در شکل ۴ را دریافت کردیم که تخمین ۱۶٫۴۳۱۷ درصدی را نشان می دهد.

شکل ۴ : طرحی که تخمین ۱۶٫۴۳۱۷ درصد را نشان می دهد

هنگام استفاده از گزاره Like در تمام سناریوهای optimize for unknown ، چه با CE به ارث مانده و چه با CE جدید از یک تخمین ۹درصدی استفاده می شود. در این مثال از متغیرهای محلی استفاده شده است:

DECLARE @Carrier AS NVARCHAR(50) = N’4911-403C-%’;
SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE CarrierTrackingNumber LIKE @Carrier

GROUP BY ProductID;
شما همان تخمین ۹درصدی را که در شکل ۳ نشان داده شده، خواهید دید گرچه در این مورد عدد واقعی سطرها ۱۲ و در مورد قبلی ۳ بود.
تخمین های optimize for unknown برای اپراتور =
هنگام استفاده از اپراتور = سه مورد اصلی وجود دارد:

ستون یونیک
ستون غیریونیک و چگلالی موجود
ستون غیریونیک و چگالی غیر موجود
وقتی ستون فیلتر شده یونیک باشد (دارای یک شاخص یونیک، PRIMARY KEY یا ثابت UNIQUE تعریف شده در آن) بهینه ساز می دارند که نمی تواند بیش از یک همتا (match) وجود داشته باشد، بنابراین به سادگی ۱ را تخمین می زند. این پرس و جو این موضوع را ثابت می کند:
DECLARE @rowguid AS UNIQUEIDENTIFIER = ‘B207C96D-D9E6-402B-8470-2CC176C42283′;
SELECT *

FROM Sales.SalesOrderDetail

WHERE rowguid = @rowguid;

شکل ۵ شامل طرح این پرس و جو است که تخمین ۱ را نشان می دهد
شکل ۵ : تخمین ۱ برای اپراتور = با یک ستون یونیک

وقتی ستون غیریونیک است و چگالی (درصد متوسط بازای هر مقدار distinct) اطلاعات برای بهینه ساز قابل دسترس می باشد، تخمین براساس چگالی خواهد بود. اگر ساخت خودکار آمار را غیرفعال نکرده اید یا دارای شاخصی هستید که در ستون ساخته شده، این اطلاعات در دسترس بهینه ساز خواهد بود. برای اثبات این مسئله، ابتدا مطمئن شوید که ساخت خودکار آمار فعال است، این کار را با اجرای کد زیر انجام دهید:
ALTER DATABASE AdventureWorks2014 SET AUTO_CREATE_STATISTICS ON;

بعد پرس و جوی زیر را اجرا کنید:

DECLARE @Qty AS INT = 1;
SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty = @Qty

GROUP BY ProductID;

شکل ۶ : طرحی که تخمین را براساس چگالی نشان می دهد
بخاطر داشته باشید که چگالی، درصد متوسط هر مقدار distinct در ستون است که بصورت ۱/<distinct-values محاسبه می شود. ۴۱ مقدار distict در ستون OrderQty وجود دارند، بنابراین ۱/۱۴۱=۰٫۰۲۴۳۹٫ اگر از این درصد در کاردینالیتی جدول استفاده می کنید، مقداری را دریافت می کنید که بسیار نزدیک به تخمین شکل ۶ است. برای دیدن اطلاعات چگالی که SQL Server استفاده کرده است، کد زیر را اجرا کنید (با استفاده از نام آماری که از پرس و جوی ارائه شده در لیست ۱ دریافت کرده اید).

DBCC SHOW_STATISTICS (N’Sales.SalesOrderDetail’, N’_WA_Sys_00000004_44CA3770′)
WITH DENSITY_VECTOR;
ما این خروجی را دریافت کردیم:
All density Average Length Columns
————- ————– ———-
۰٫۰۲۴۳۹۰۲۴ ۲ OrderQty

متوجه خواهید شد که این متدِ مبتنی برچگالی کلاً برای شما خوب است وقتی در حقیقت ورودی هایی که شما پرس و جو می کنید اغلب دارای کار دینالیتی هستند که نزدیک به کار دینالیتی میانگین می باشد. مشخصا این موضوع در مورد مثال آخر ما صادق نیست. کمیت ۱ بسیار بیشتر از میانگین ظاهر می شود، بنابراین عدد واقعی بزرگتر از تخمین است.
هنگامیکه از یک ستون غیریونیک استفاده می کنید و چگالی هم موجود نیست، CE به ارث مانده و CE جدید از روش های کمی متفاوت استفاده می کنند. CE به ارث مانده از تخمین C^0.75 استفاده می کند.
برای اثبات این موضوع، ابتدا تمامی آمار را در ستون OrderQty حذف کنید و ساخت خودکار آمار را به روشی که قبلا نشان دادیم، غیرفعال نمائید:

ALTER DATABASE AdventureWorks2014 SET AUTO_CREATE_STATISTICS OFF;

GO

DROP STATISTICS Sales.SalesOrderDetail._WA_Sys_00000004_44CA3770;

از کد زیر برای آزمایش متد CE به ارث مانده استفاده نمائید:

DECLARE @Qty AS INT = 1;
SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty = @Qty

GROUP BY ProductID

OPTION(QUERYTRACEON 9481);
طرح مربوط به این پرس و جو در شکل ۷ آمده است.

شکل ۷ : طراحی که تخمین C^3/4، CE به ارث مانده را نشان می دهد

تخمین ۶۵۰۰٫۴۲ نتیجه ۱۲۱۳۱۷^۳/۴ است.
از کد زیر برای آزمایش روش CE جدید استفاده کنید:

DECLARE @Qty AS INT = 1;
SELECT ProductID, COUNT(*) AS NumOrders

FROM Sales.SalesOrderDetail

WHERE OrderQty = @Qty

GROUP BY ProductID;

طرح مربوط به این پرس و جو در شکل ۸ آمده است.
شکل ۸: طراحی که تخمین C^0.5 ، CE جدید را نشان می دهد

تخمین ۳۴۸٫۳۰۶ نتیجه ۱۲۱۳۱۷^۰٫۵ است.
وقتی این آزمایش را انجام می دهید، مطمئن شوید که ساخت خودکار آمار را با اجرای کد زیر مجدد فعال کرده اید:
ALTER DATABASE AdventureWorks2014 SET AUTO_CREATE_STATISTICS ON;
خلاصه
تکنیک optimize-for unknown توسط بهینه ساز SQL Server استفاده می شود تا تخمین های کاردینالیتی را برای ورودی های ناشناخته یا در صورت عدم وجود آمار انجام دهد. گاهی اوقات بهینه ساز هیچ راهی جز استفاده از این روش ندارد چون اطلاعات را از دست داده است و گاهی اوقات شما می خواهید بهینه ساز را مجبور به این کار کنید وقتیکه تکنیک optimize-for-known برای شما خوب نیست. در این مقاله به جزییات زیادی پرداخته شده است. بطور خلاصه تکنیک optimize for unknown برای سناریوهای زیر بکار می رود:
۱- استفاده از متغیرها (مگر آنکه از RECOMPILE سطح دستور استفاده شده باشد)
۲- استفاده از پارامترها: با OPTIMIZE FOR UNKNOWN یا hint OPTIMIZE FOR (@parameter Unknown) یا TF4136(همیشه در مورد رویه های ذخیره شده ای که بطور بومی کامپایل شده اند).
۳- آمارهایی که در دسترس نیستند.
جدول ۲شامل خلاصه ای از تخمین های optimize-for-unknwon به کار رفته برای گروه های مختلف اپراتورهاست.

جدول ۲ : تخمین های optimize for unknown برای اپراتورها

دیدگاهتان را ثبت کنید

آدرس ایمیل شما منتشر نخواهد شدعلامتدارها لازمند *

*

x

شاید بپسندید

تنظیم پرس و جوی SQL Server یک برنامه ۱۲ مرحله‌ای

تنظیم پرس و جوی SQL Server یک برنامه ۱۲ مرحله‌ای مقدمه: تنظیم ...