আমার কাছে এসআরজিবিলিটি সম্পর্কে একটি আকর্ষণীয় প্রশ্ন রয়েছে। এই ক্ষেত্রে, এটি দুটি তারিখের কলামের মধ্যে পার্থক্য সম্পর্কে একটি প্রিকিকেট ব্যবহার করার বিষয়ে। এখানে সেটআপ দেওয়া আছে:
USE [tempdb]
SET NOCOUNT ON
IF OBJECT_ID('tempdb..#sargme') IS NOT NULL
BEGIN
DROP TABLE #sargme
END
SELECT TOP 1000
IDENTITY (BIGINT, 1,1) AS ID,
CAST(DATEADD(DAY, [m].[severity] * -1, GETDATE()) AS DATE) AS [DateCol1],
CAST(DATEADD(DAY, [m].[severity], GETDATE()) AS DATE) AS [DateCol2]
INTO #sargme
FROM sys.[messages] AS [m]
ALTER TABLE [#sargme] ADD CONSTRAINT [pk_whatever] PRIMARY KEY CLUSTERED ([ID])
CREATE NONCLUSTERED INDEX [ix_dates] ON [#sargme] ([DateCol1], [DateCol2])
আমি প্রায়শই যা দেখতে পাচ্ছি তা হ'ল এটির মতো:
/*definitely not sargable*/
SELECT
* ,
DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2])
FROM
[#sargme] AS [s]
WHERE
DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2]) >= 48;
... যা অবশ্যই SARGable নয় G এটি একটি সূচক স্ক্যানের ফলস্বরূপ, সমস্ত 1000 সারি পড়ে, কোনও ভাল নয়। আনুমানিক সারি দুর্গন্ধ। আপনি এটি কখনও উত্পাদন করতে চাই না in
এটি ভাল লাগবে যদি আমরা সিটিইগুলি বাস্তবায়িত করতে পারি, কারণ এটি আমাদের প্রযুক্তিগতভাবে বলার জন্য এটি আরও ভাল করে তৈরি করতে সহায়তা করবে। তবে না, আমরা শীর্ষ হিসাবে একই কার্যকরকরণ পরিকল্পনাটি পাই।
/*would be nice if it were sargable*/
WITH [x] AS ( SELECT
* ,
DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2]) AS [ddif]
FROM
[#sargme] AS [s])
SELECT
*
FROM
[x]
WHERE
[x].[ddif] >= 48;
এবং অবশ্যই, যেহেতু আমরা ধ্রুবকগুলি ব্যবহার করছি না, এই কোডটি কিছুই পরিবর্তন করে না, এবং অর্ধেক SARGableও নয়। মজা নেই। একই বাস্তবায়ন পরিকল্পনা।
/*not even half sargable*/
SELECT
* ,
DATEDIFF(DAY, [s].[DateCol1], [s].[DateCol2])
FROM
[#sargme] AS [s]
WHERE
[s].[DateCol2] >= DATEADD(DAY, 48, [s].[DateCol1])
আপনি যদি ভাগ্যবান বোধ করছেন এবং আপনি যদি আপনার সংযোগের স্ট্রিংগুলিতে সমস্ত এএনএসআই সেট বিকল্পগুলি মানছেন, আপনি একটি গণিত কলাম যুক্ত করতে পারেন এবং এটি অনুসন্ধান করতে পারেন ...
ALTER TABLE [#sargme] ADD [ddiff] AS
DATEDIFF(DAY, DateCol1, DateCol2) PERSISTED
CREATE NONCLUSTERED INDEX [ix_dates2] ON [#sargme] ([ddiff], [DateCol1], [DateCol2])
SELECT [s].[ID] ,
[s].[DateCol1] ,
[s].[DateCol2]
FROM [#sargme] AS [s]
WHERE [ddiff] >= 48
এটি আপনাকে তিনটি প্রশ্নের সাথে একটি সূচি সন্ধান করবে। বিজোড় মানুষটি হ'ল আমরা তারিখ 1 এ 48 দিন যুক্ত করি। সঙ্গে ক্যোয়ারী DATEDIFF
মধ্যে WHERE
দফা, CTE
কম্পিউটেড কলাম একটি বিধেয় সঙ্গে, এবং চূড়ান্ত ক্যোয়ারী সব অনেক nicer অনুমান সঙ্গে একটি অনেক nicer পরিকল্পনা যে সব দিতে, এবং।
যা আমাকে প্রশ্নে নিয়ে আসে: একটি একক ক্যোয়ারিতে, এই অনুসন্ধানটি করার কোনও SARGable উপায় আছে কি?
কোনও টেম্প টেবিল নেই, কোনও টেবিলের ভেরিয়েবল নেই, কোনও টেবিলের কাঠামোর পরিবর্তন হবে না এবং কোনও দর্শন নেই।
আমি স্ব-যোগদান করে, সিটিই, সাবকোয়ারি বা ডেটা একাধিক পাস দিয়ে ভাল fine এসকিউএল সার্ভারের যে কোনও সংস্করণ নিয়ে কাজ করতে পারে।
গণিত কলামটি এড়ানো একটি কৃত্রিম সীমাবদ্ধতা কারণ আমি অন্য কোনও কিছুর চেয়ে ক্যোয়ারী সমাধানে বেশি আগ্রহী।