کاربرد دستور OPTION (RECOMPILE, OPTIMIZE FOR UNKNOWN) در SQL

دستور 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 برای مقدار واقعی پارامتر بهینه نمی‌شود بلکه برای "مقدار ناشناخته" بهینه‌سازی می‌شود.

تبدیل تاریخ میلادی به شمسی در SQL

DECLARE @today DATE = GETDATE();

SELECT FORMAT(@today, 'yyyy-MM-dd', 'fa-IR') AS PersianDate;

ایجاد روزهای سال شمسی با Stored Peocedure در Sql Server

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

بررسی میزان حافظه اشغال شده در SQLServer

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

جهت انجام تاخیر در دستورات TSQL باید از دستور زیر استفاده شود:

WAITFOR DELAY '00:00:01'

XML در خروجی tSQL

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

نمایش تاریخ بدون زمان در T-SQL

select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

بررسی اطلاعات پوچ در توابع SQL

ISNULL   (   [column name]   ,   [value]   )
Exapm;e:
SELECT ProductName,UnitPrice*(UnitsInStock+ISNULL(UnitsOnOrder,0))
FROM Products

مشاهده حجم یک جدول

sp_spaceused [نام جدول]

sp_spaceused tblkala

تغییر Data Type در SQL Server

ALTER TABLE table_name

ALTER COLUMN column_name datatype