এই প্যাটার্ন
column = @argument OR (@argument IS NULL AND column IS NULL)
সঙ্গে প্রতিস্থাপন করা যেতে পারে
EXISTS (SELECT column INTERSECT SELECT @argument)
এটি আপনাকে একটি NULL এর সাথে একটি NUL এর সাথে মিলিয়ে দেবে এবং ইঞ্জিনটিকে column
দক্ষতার সাথে একটি সূচক ব্যবহার করার অনুমতি দেবে । এই কৌশলটির দুর্দান্ত গভীর-বিশ্লেষণের জন্য, আমি আপনাকে পল হোয়াইটের ব্লগ নিবন্ধটি উল্লেখ করছি:
আপনার নির্দিষ্ট ক্ষেত্রে যেমন দুটি যুক্তি রয়েছে, আপনি একই মেলানো কৌশলটি ব্যবহার করতে পারেন @Blah
- এইভাবে আপনি আরও বা কম সংক্ষেপে পুরো WHERE ধারাটি পুনরায় লিখতে সক্ষম হবেন:
WHERE
EXISTS (SELECT a.Blah, a.VersionId INTERSECT SELECT @Blah, @VersionId)
এটি সূচক চালু রেখে দ্রুত কাজ করবে (a.Blah, a.VersionId)
।
অথবা ক্যোয়ারী অপ্টিমাইজার এটিকে মূলত একই করে তোলে?
এই ক্ষেত্রে, হ্যাঁ। এসকিউএল সার্ভার ২০০৫ সাল থেকে সমস্ত সংস্করণে (কমপক্ষে), অপ্টিমাইজার প্যাটার্নটি সনাক্ত করতে পারে col = @var OR (@var IS NULL AND col IS NULL)
এবং এটিকে যথাযথ IS
তুলনার সাথে প্রতিস্থাপন করতে পারে । এটি অভ্যন্তরীণ পুনর্লিখনের মিলের উপর নির্ভর করে, তাই আরও জটিল কিছু ক্ষেত্রে থাকতে পারে যেখানে এটি সর্বদা নির্ভরযোগ্য নয়।
SQL সার্ভার এর সংস্করণে 2008 এসপি 1 CU5 সমেত থেকে , এছাড়াও আপনি ব্যবহার করার অপশন আছে প্যারামিটার এমবেডিং অপ্টিমাইজেশান মাধ্যমে OPTION (RECOMPILE)
, যেখানে কোনো প্যারামিটার বা ভেরিয়েবলের রানটাইম মান সংকলন আগে একটি আক্ষরিক যেমন ক্যোয়ারীতে এমবেড করা হয়।
সুতরাং, কমপক্ষে একটি বৃহত পরিমাণে, এই ক্ষেত্রে পছন্দটি স্টাইলের বিষয়, যদিও INTERSECT
নির্মাণটি অনস্বীকার্যভাবে কমপ্যাক্ট এবং মার্জিত।
নিম্নলিখিত উদাহরণগুলি প্রতিটি পরিবর্তনের জন্য 'একই' কার্যকরকরণ পরিকল্পনাটি দেখায় (আক্ষরিক বনাম চলক উল্লেখগুলি বাদ দেওয়া হয়):
DECLARE @T AS table
(
c1 integer NULL,
c2 integer NULL,
c3 integer NULL
UNIQUE CLUSTERED (c1, c2)
);
-- Some data
INSERT @T
(c1, c2, c3)
SELECT 1, 1, 1 UNION ALL
SELECT 2, 2, 2 UNION ALL
SELECT NULL, NULL, NULL UNION ALL
SELECT 3, 3, 3;
-- Filtering conditions
DECLARE
@c1 integer,
@c2 integer;
SELECT
@c1 = NULL,
@c2 = NULL;
-- Writing the NULL-handling out explicitly
SELECT *
FROM @T AS T
WHERE
(
T.c1 = @c1
OR (@c1 IS NULL AND T.c1 IS NULL)
)
AND
(
T.c2 = @c2
OR (@c2 IS NULL AND T.c2 IS NULL)
);
-- Using INTERSECT
SELECT *
FROM @T AS T
WHERE EXISTS
(
SELECT T.c1, T.c2
INTERSECT
SELECT @c1, @c2
);
-- Using separate queries
IF @c1 IS NULL AND @c2 IS NULL
SELECT *
FROM @T AS T
WHERE T.c1 IS NULL
AND T.c2 IS NULL
ELSE IF @c1 IS NULL
SELECT *
FROM @T AS T
WHERE T.c1 IS NULL
AND T.c2 = @c2
ELSE IF @c2 IS NULL
SELECT *
FROM @T AS T
WHERE T.c1 = @c1
AND T.c2 IS NULL
ELSE
SELECT *
FROM @T AS T
WHERE T.c1 = @c1
AND T.c2 = @c2;
-- Using OPTION (RECOMPILE)
-- Requires 2008 SP1 CU5 or later
SELECT *
FROM @T AS T
WHERE
(
T.c1 = @c1
OR (@c1 IS NULL AND T.c1 IS NULL)
)
AND
(
T.c2 = @c2
OR (@c2 IS NULL AND T.c2 IS NULL)
)
OPTION (RECOMPILE);