بهبود کارایی کوئری در LINQ

ممکن هست بدون توجه به Performance ایجاد شده از دستورات LINQ، دیتایی رو از Data Sourceها دریافت کنید اما غافل از اینکه سیستم شما بهای بیشتری رو در قبال کوئری ایجاد شده توسط شما خواهد پرداخت!

به خروجی SQL مثالهای زیر دقت کنید:

var sqlCommand = from a in context.Requests
				 where a.CreateDate >= DateTime.Today && a.CreateDate < DateTime.Today.AddDays(1)
				 && a.BranchCode == branchCode &&
				 a.StatusId == (int)PaymentRequestStatus_DOM.enmPaymentRequest_Status.SampleStatus
				 select a;
DECLARE @__branchCode_0 int = 199;

SELECT *
FROM [Requests] AS [p]
WHERE ((([p].[CreateDate] >= CONVERT(date, GETDATE())) AND ([p].[CreateDate] < DATEADD(day, CAST(1.0E0 AS int), CONVERT(date, GETDATE())))) AND ([p].[BranchCode] = @__branchCode_0)) AND ([p].[StatusId] = 300)

DateTime beginDate = DateTime.Today;
DateTime endDate = DateTime.Today.AddDays(1);

var sqlCommand = from a in context.Requests
				 where a.CreateDate >= beginDate && a.CreateDate < endDate
				 && a.BranchCode == branchCode &&
				 a.StatusId == (int)PaymentRequestStatus_DOM.enmPaymentRequest_Status.SampleStatus
				 select a;
DECLARE @__beginDate_0 datetime = '2022-07-04T00:00:00.000';
DECLARE @__endDate_1 datetime = '2022-07-05T00:00:00.000';
DECLARE @__8__locals1_branchCode_2 int = 199;

SELECT *
FROM [Requests] AS [p]
WHERE ((([p].[CreateDate] >= @__beginDate_0) AND ([p].[CreateDate] < @__endDate_1)) AND ([p].[BranchCode] = @__8__locals1_branchCode_2)) AND ([p].[StatusId] = 300)

در خروجی SQL مثال اول مشاهده می‌کنید که یک تعیین تاریخ ساده تبدیل به چند تابع شده اما در خروجی SQL دوم این موارد تبدیل به پارامتر شدند. بنابراین اجرای این کوئری هزینه کمتری را برای سیستم شما خواهد داشت.

البته موارد دیگری هم برای بهبود وجود دارند، مثلاً زمانی که شما از یک کوئری فقط چند فیلد نیاز دارید، راه درست این هست که داخل دستور LINQ فیلدهایی که نیاز دارید رو بیرون بکشید و راه غلط این هست که اول یه SELECT روی جدول بزنید و بعد از روی خروجی فیلدهاتون رو بیرون بکشید.

راه غلط:

var customer =
	(from cust in dataContext.Customers
	 where cust.ID == customerID
	 select cust).Single();
var customerLite = new {
	customer.FirstName,
	customer.LastName,
	customer.Email
};

راه درست:

var customerLite =
	(from cust in dataContext.Customers
	 where cust.ID == customerID
	 select new {
		customer.FirstName,
		customer.LastName,
		customer.Email
	 }).Single();

مورد بعدی در بهبود کارایی این هست که تعداد پارامترهایی که قرار هست در دستورات خودتون استفاده کنید رو کاهش بدید چون هر چی تعداد این پارامترها کمتر بشه، دستور SQL ساخته شده ساده‌تر خواهد بود.

و مورد آخر اینکه اگر نسبت به کوئری LINQ نوشته شده شک دارید، حتماً خروجی SQL حاصل از اون رو بررسی کنید و کوئری رو مطابق نظرتون اصلاح کنید.