آموزش غیرفعال کردن مرتب سازی Join های SQL با Optimizer Engine

برای اجراء یک دستور Query یکسری عملیاتی باید انجام گیرد که SQL Server بتواند آن Query را اجراء نماید. یکی از این عملیات Optimization نام دارد که توسط Optimizer Engine انجام می شود. در این قسمت از عملیات SQL Server سعی می کند در مدت زمان محدود یکی از بهترین Execution Plan ها را ساخته و در اختیار Query Executor قرار دهد. در حین ساخت Execution Plan تمامی اجزاء دستور Query حتی ترتیب قرار گرفتن JOIN ها بررسی شده و بهترین حالت آن به عنوان خروجی ذخیره می شود. SQL Server ترتیب JOIN ها را به این دلیل تغییر می دهد که ممکن است ترتیب داده شده بهینه نباشد و موجب استفاده بیش از حد منابع سیستم گردد. به عنوان مثال به دستور زیر توجه کنید:

دوره های شبکه، برنامه نویسی، مجازی سازی، امنیت، نفوذ و ... با برترین های ایران
SELECT * FROM TableA A 
	INNER Join TableC C ON C.ID = A.ID 
	INNER Join TableB B ON B.ID = C.ID

در دستور بالا SQL Server به سه مدل ترتیبی JOIN ها به صورت زیر می پردازد:

  1. A JOIN B) JOIN C)
  2. A JOIN C) JOIN B)
  3. B JOIN C) JOIN A)

همانطور که مشاهده می کنید سه نوع متفاوت از ترکیب JOIN ها بوجود آمده است. بیشتر توسعه دهنده گان پایگاه داده بر این باوراند که ترتیب JOIN ها همانطوری است که در دستور آمده. اما باید ذکر کنم که خیر! اینطور نیست. بگذارید با یک مثال شروع کنم:

  • توجه: دستورات زیر فقط برای نشان دادن قابلیت SQL Server است و استفاده از این دستورات در محیط اصلی یا Production باعث بروز خطا و پایین آمدن بازدهی سیستمی می شود. لذا از اجراء آن در سیستم اصلی خودداری فرماید.

کد زیر سه جدول ساخته و آنها را از داده پر می کند.

USE tempdb;
go
CREATE TABLE TableA (ID INT Not Null, Content VARCHAR(10));
Go
CREATE TABLE TableB (ID INT Not Null, Content VARCHAR(10));
Go
CREATE TABLE TableC (ID INT Not Null, Content VARCHAR(10));
Go
 
INSERT INTO TableA (ID,Content) VALUES (1,'A'),(2,'B'),(3,'C');
Go
INSERT INTO TableB (ID,Content) VALUES (1,'A'),(2,'B'),(3,'C');
Go
INSERT INTO TableC (ID,Content) VALUES (1,'A'),(2,'B'),(3,'C');
Go
 
ALTER TABLE TableA
	ADD CONSTRAINT PK_A PRIMARY KEY CLUSTERED (ID);
Go
ALTER TABLE TableB
	ADD CONSTRAINT PK_B PRIMARY KEY CLUSTERED (ID);
Go
ALTER TABLE TableC
	ADD CONSTRAINT PK_C PRIMARY KEY CLUSTERED (ID);
Go

در مرحله بعد دستور Query زیر را اجراء می کنیم و یک نگاهی به Actual Execution Plan می اندازیم.

SELECT * FROM TableA A 
	INNER Join TableC C ON C.ID = A.ID 
	INNER Join TableB B ON B.ID = C.ID
وب سایت توسینسو

همانطور که در تصویر بالا مشاهده می کنید SQL Server Optimizer Engine ترتیب A JOIN B) JOIN C) را در نظر گرفت که این با ترتیب واقع شده در دستور یکی نیست.با دستور OPTION (FORCE ORDER) شما می توانید قابلیت مرتب سازی خودکار JOIN ها را غیر فعال کنید.

SELECT * FROM TableA A 
	INNER Join TableC C ON C.ID = A.ID 
	INNER Join TableB B ON B.ID = C.ID
	OPTION (Force ORDER)

البته این کار با دستور OPTION (QUERYRULEOFF JOINCOMMUTE) هم قابل اجراء است.

SELECT * FROM TableA A 
	INNER Join TableC C ON C.ID = A.ID 
	INNER Join TableB B ON B.ID = C.ID
	OPTION (QueryRuleOff JoinCommute);
وب سایت توسینسو

همانطور که در تصویر بالا مشاهده می کنید SQL Server Optimizer Engine ترتیب JOIN ها را به طور کلی همانند دستور Query اجراء کرده است.


حمید ج. فرد
حمید ج. فرد

متخصص پایگاه داده SQL Server Microsoft Certified Master: SQL Server 2008 Microsoft Certified Solutions Master: Charter - Data Platform Microsoft Certified Solutions Expert: Data Platform Microsoft Certified Solutions Associate: SQL Server 2012 Microsoft Certified IT Professional Microsoft Certified Technology Specialist Microsoft Certified Professional Developer Microsoft Certified Trainer CIW Database Design Specialist

نظرات