دستور OPTION (RECOMPILE, OPTIMIZE FOR UNKNOWN) در SQL Server یکی از گزینههای Query Hint است که رفتار Optimizer رو روی اجرای یک کوئری خاص کنترل میکنه. بذار مرحلهبهمرحله توضیح بدم:
1. RECOMPILE
این بخش باعث میشود که SQL Server هر بار که کوئری اجرا میشود، یک Plan جدید بسازد و از Execution Plan ذخیرهشده قبلی استفاده نکند.
چرا لازم میشود؟
* وقتی دادهها یا پراکندگی دادهها (Data Distribution) خیلی متغیر هستند، استفاده از Plan قبلی ممکن است کارایی ضعیفی داشته باشد.
* مخصوصاً برای کوئریهایی که دارای پارامتر هستند و مقادیر پارامترهای مختلف باعث تغییر شدید تعداد ردیفها میشود.
مثال:
SELECT *
FROM Orders
WHERE CustomerID = @CustID
OPTION (RECOMPILE);
SQL Server هر بار که این کوئری اجرا شود، با مقدار واقعی @CustID Plan جدید میسازد.
2. OPTIMIZE FOR UNKNOWN
این گزینه به Optimizer میگوید فرض کند که هیچ اطلاعات خاصی از پارامترها ندارد و Plan را بر اساس آمار کلی جدول بسازد، نه بر اساس مقادیر واقعی پارامترها.
مزایا:
* وقتی دادهها خیلی نامتوازن هستند (مثلاً بعضی مقادیر پارامتر خیلی پرت هستند)، این گزینه از parameter sniffing problem جلوگیری میکند.
* به جای اینکه Plan برای یک مقدار خاص پارامتر بهینه شود، Planی عمومی ساخته میشود.
مثال:
SELECT *
FROM Orders
WHERE CustomerID = @CustID
OPTION (OPTIMIZE FOR UNKNOWN);
SQL Server از آماری استفاده میکند که برای تمام دادهها معتبر باشد، نه فقط مقدار @CustID.
نکته مهم:
میتوان این دو را با هم استفاده کرد:
SELECT *
FROM Orders
WHERE CustomerID = @CustID
OPTION (RECOMPILE, OPTIMIZE FOR UNKNOWN);
هر بار که کوئری اجرا شود، Plan جدید ساخته میشود و این Plan برای مقدار واقعی پارامتر بهینه نمیشود بلکه برای "مقدار ناشناخته" بهینهسازی میشود.
DECLARE @today DATE = GETDATE();
SELECT FORMAT(@today, 'yyyy-MM-dd', 'fa-IR') AS PersianDate;
declare @date as int
declare @day as int
declare @month as int
set @date=14030101
set @day=1
set @month=1
create table #tblDate (
[dt] int,
[myDay] int
);
while (@month<=12)
begin
insert into #tblDate (dt, myDay) values (@date, @day)
set @day = @day + 1
if (@month<7) and (@day>31)
begin
set @day= 1
set @month = @month + 1
set @date = @date + 70
end
else if (@month>6) and (@day>30)
begin
set @day= 1
set @month = @month + 1
set @date = @date + 71
end
else
set @date = @date + 1
end
delete from #tblDate where dt=(select top 1 dt from #tblDate order by dt desc)
select * from #tblDate
drop table #tblDate
SELECT DB_NAME(database_id),
COUNT (1) * 8 / 1024 AS MBUsed
FROM sys.dm_os_buffer_descriptors
GROUP BY database_id
ORDER BY COUNT (*) * 8 / 1024 DESC
GO
جهت انجام تاخیر در دستورات TSQL باید از دستور زیر استفاده شود:
WAITFOR DELAY '00:00:01'
SELECT dbo.staff.id, dbo.staff.fullName, dbo.staff.dressCode, dbo.staff.lockerCode, dbo.staff.staffCode,
[dbo].[getCountOfStaffUnavailableDocumnet](dbo.staff.id) as unavailableDocumnet,
(select ' - ' + titleFa from allType where parent = 228 and id not in (select documentType from staffDocument where staff_id=dbo.staff.id)
and id not in(231,236,248,251,255,256)
order by titleFa
FOR XML PATH('')) as unavailableDocumnetTitle,
allType_restaurant.titleFa AS restaurant, allType_position.titleFa AS position, allType_jobStatus.titleFa AS jobStatus
FROM dbo.staff INNER JOIN
dbo.allType AS allType_restaurant ON dbo.staff.restaurant = allType_restaurant.id INNER JOIN
dbo.allType AS allType_position ON dbo.staff.position = allType_position.id INNER JOIN
dbo.allType AS allType_jobStatus ON dbo.staff.jobStatus = allType_jobStatus.id
ORDER BY dbo.staff.id DESC
select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)