डिस्क्लेमर : इस उत्तर में कुछ सामान डीबीए फ्लिंच बना सकते हैं। मैं इसे एक शुद्ध प्रदर्शन के दृष्टिकोण से ले जा रहा हूं - जब आप हमेशा इंडेक्स स्कैन्स प्राप्त करते हैं तो इंडेक्स सॉक्स कैसे प्राप्त करें।
उस रास्ते से, यहाँ चला जाता है।
आपकी क्वेरी को "किचन सिंक क्वेरी" के रूप में जाना जाता है - संभव खोज स्थितियों की एक श्रृंखला को पूरा करने के लिए एक एकल क्वेरी। यदि उपयोगकर्ता @status
किसी मान पर सेट होता है, तो आप उस स्थिति को फ़िल्टर करना चाहते हैं। यदि @status
है NULL
, तो सभी स्थितियों को वापस करें, और इसी तरह।
यह अनुक्रमण के साथ समस्याओं का परिचय देता है, लेकिन वे sargability से संबंधित नहीं हैं, क्योंकि आपकी सभी खोज स्थितियां "मानदंड के बराबर" हैं।
यह सारगर्भित है:
WHERE [status]=@status
यह व्यर्थ नहीं है क्योंकि एसक्यूएल सर्वर ISNULL([status], 0)
को इंडेक्स में एकल मान देखने के बजाय हर पंक्ति के लिए मूल्यांकन करने की आवश्यकता होती है:
WHERE ISNULL([status], 0)=@status
मैंने सरल रूप में रसोई सिंक-समस्या को फिर से बनाया है:
CREATE TABLE #work (
A int NOT NULL,
B int NOT NULL
);
CREATE UNIQUE INDEX #work_ix1 ON #work (A, B);
INSERT INTO #work (A, B)
VALUES (1, 1), (2, 1),
(3, 1), (4, 1),
(5, 2), (6, 2),
(7, 2), (8, 3),
(9, 3), (10, 3);
यदि आप निम्नलिखित प्रयास करते हैं, तो आपको एक इंडेक्स स्कैन मिलेगा, भले ही ए इंडेक्स का पहला कॉलम हो:
DECLARE @a int=4, @b int=NULL;
SELECT *
FROM #work
WHERE (@a IS NULL OR @a=A) AND
(@b IS NULL OR @b=B);
यह, हालांकि, एक इंडेक्स सीक का उत्पादन करता है:
DECLARE @a int=4, @b int=NULL;
SELECT *
FROM #work
WHERE @a=A AND
@b IS NULL;
जब तक आप मापदंडों की एक प्रबंधनीय राशि (आपके मामले में दो) का उपयोग कर रहे हैं, तब तक आप शायद केवल UNION
प्रश्नों का एक गुच्छा हो सकते हैं - मूल रूप से खोज मानदंडों के सभी क्रमपरिवर्तन। यदि आपके पास तीन मानदंड हैं, तो यह गड़बड़ दिखेगी, चार के साथ यह पूरी तरह असहनीय होगा। आपको चेतावनी दी गई थी।
DECLARE @a int=4, @b int=NULL;
SELECT *
FROM #work
WHERE @a=A AND
@b IS NULL
UNION ALL
SELECT *
FROM #work
WHERE @a=A AND
@b=B
UNION ALL
SELECT *
FROM #work
WHERE @a IS NULL AND
@b=B
UNION ALL
SELECT *
FROM #work
WHERE @a IS NULL AND
@b IS NULL;
इंडेक्स सीक का उपयोग करने के लिए उन चार में से एक के लिए, आपको दूसरे इंडेक्स की आवश्यकता होगी (B, A)
, हालांकि। यहां बताया गया है कि आपकी क्वेरी इन परिवर्तनों के साथ कैसे दिखाई दे सकती है (इसे और अधिक पठनीय बनाने के लिए क्वेरी को फिर से भरना सहित)।
DECLARE @Status int = NULL,
@IsUserGotAnActiveDirectoryUser bit = NULL;
SELECT [IdNumber], [Code], [Status], [Sex], [FirstName], [LastName],
[Profession], [BirthDate], [HireDate], [ActiveDirectoryUser]
FROM Employee
WHERE [Status]=@Status AND
@IsUserGotAnActiveDirectoryUser IS NULL
UNION ALL
SELECT [IdNumber], [Code], [Status], [Sex], [FirstName], [LastName],
[Profession], [BirthDate], [HireDate], [ActiveDirectoryUser]
FROM Employee
WHERE [Status]=@Status AND
@IsUserGotAnActiveDirectoryUser=1 AND ActiveDirectoryUser<>''
UNION ALL
SELECT [IdNumber], [Code], [Status], [Sex], [FirstName], [LastName],
[Profession], [BirthDate], [HireDate], [ActiveDirectoryUser]
FROM Employee
WHERE [Status]=@Status AND
@IsUserGotAnActiveDirectoryUser=0 AND (ActiveDirectoryUser IS NULL OR ActiveDirectoryUser='')
UNION ALL
SELECT [IdNumber], [Code], [Status], [Sex], [FirstName], [LastName],
[Profession], [BirthDate], [HireDate], [ActiveDirectoryUser]
FROM Employee
WHERE @Status IS NULL AND
@IsUserGotAnActiveDirectoryUser IS NULL
UNION ALL
SELECT [IdNumber], [Code], [Status], [Sex], [FirstName], [LastName],
[Profession], [BirthDate], [HireDate], [ActiveDirectoryUser]
FROM Employee
WHERE @Status IS NULL AND
@IsUserGotAnActiveDirectoryUser=1 AND ActiveDirectoryUser<>''
UNION ALL
SELECT [IdNumber], [Code], [Status], [Sex], [FirstName], [LastName],
[Profession], [BirthDate], [HireDate], [ActiveDirectoryUser]
FROM Employee
WHERE @Status IS NULL AND
@IsUserGotAnActiveDirectoryUser=0 AND (ActiveDirectoryUser IS NULL OR ActiveDirectoryUser='');
... इसके अलावा आपको Employee
दो अनुक्रमणिका स्तंभों के साथ एक अतिरिक्त अनुक्रमणिका की आवश्यकता होगी ।
पूर्णता के लिए, मुझे इस बात का उल्लेख करना चाहिए कि x=@x
इसका मतलब यह है कि x
ऐसा नहीं किया जा सकता है NULL
क्योंकि NULL
कभी भी इसके बराबर नहीं है NULL
। यह क्वेरी को थोड़ा सरल करता है।
और, हाँ, हारून बर्ट्रेंड के गतिशील एसक्यूएल जवाब ज्यादातर मामलों में एक बेहतर विकल्प है (यानी जब भी आप रीकॉम्पायर के साथ रह सकते हैं)।
@Status
?