আমি প্রায়শই পড়েছি যখন কোনও সারির অস্তিত্ব পরীক্ষা করতে হয় তখন সবসময় একটি COUNT এর পরিবর্তে উপস্থিতি দিয়েই করা উচিত ।
যে কোনও কিছুর সর্বদা সত্য হওয়া খুব বিরল , বিশেষত এটি যখন ডাটাবেসে আসে। এসকিউএলে একই শব্দার্থক প্রকাশ করার জন্য বিভিন্ন ধরণের উপায় রয়েছে। যদি থাম্বের কোনও কার্যকর নিয়ম থাকে, তবে এটি উপলব্ধ সবচেয়ে প্রাকৃতিক বাক্য গঠন (এবং হ্যাঁ, এটি বিষয়গত) ব্যবহার করে কোয়েরি লিখতে পারে এবং আপনি যে ক্যোয়ারী পরিকল্পনা বা সম্পাদনটি গ্রহণ করেন তা অগ্রহণযোগ্য হলে কেবল পুনরায় লেখার বিষয়টি বিবেচনা করুন।
এটির পক্ষে মূল্যবান বিষয়গুলির জন্য, আমার নিজের বিবেচনাটি হ'ল অস্তিত্বের প্রশ্নগুলি সবচেয়ে স্বাভাবিকভাবে ব্যবহার করে প্রকাশ করা হয় EXISTS
। এটি আমার অভিজ্ঞতাও ছিল যা প্রত্যাখাত বিকল্পের চেয়ে EXISTS
আরও ভাল অনুকূলিতকরণ করতে ঝোঁক । ব্যবহার এবং ফিল্টারিং অন্য বিকল্প, এটি এসকিউএল সার্ভারের ক্যোয়ারী অপ্টিমাইজারটিতে কিছুটা সমর্থন পেতে দেখা যায়, তবে আমি ব্যক্তিগতভাবে এটি আরও জটিল প্রশ্নের ক্ষেত্রে বিশ্বাসযোগ্য না বলে খুঁজে পেয়েছি। যাই হোক, শুধু অনেক বেশি (রা) আমাকে ঐ বিকল্প যেকোন তুলনায় প্রাকৃতিক বলে মনে হয়।OUTER JOIN
NULL
COUNT(*)
=0
EXISTS
আমি ভাবছিলাম যে যদি উপস্থিতিগুলির সাথে একটি নিরবচ্ছিন্ন ত্রুটি আছে যা আমি যে পরিমাপগুলি করেছি তার পুরোপুরি ধারণা পেয়েছে
আপনার নির্দিষ্ট উদাহরণটি আকর্ষণীয়, কারণ এটি CASE
অভিব্যক্তিতে সাবকিউরিয়াদের (এবং EXISTS
বিশেষত পরীক্ষাগুলি) সাথে অনুকূলিতকরণের উপায়টি হাইলাইট করে ।
CASE এর এক্সপ্রেশনগুলিতে সাবক্রিওরিগুলি
নিম্নলিখিত (পুরোপুরি আইনী) ক্যোয়ারী বিবেচনা করুন:
DECLARE @Base AS TABLE (a integer NULL);
DECLARE @When AS TABLE (b integer NULL);
DECLARE @Then AS TABLE (c integer NULL);
DECLARE @Else AS TABLE (d integer NULL);
SELECT
CASE
WHEN (SELECT W.b FROM @When AS W) = 1
THEN (SELECT T.c FROM @Then AS T)
ELSE (SELECT E.d FROM @Else AS E)
END
FROM @Base AS B;
এর শব্দার্থবিদ্যাCASE
যে WHEN/ELSE
ক্লজ হয় সাধারণত পাঠগত অনুক্রমে মূল্যায়ন করেন। উপরের ক্যোয়ারিতে, এসকিউএল সার্ভারের ELSE
যদি WHEN
অনুচ্ছেদটি সন্তুষ্ট হয় তবে সাবকিউরিটি একাধিক সারিতে ফেরত দিলে ত্রুটি ফিরে পাওয়া ভুল হবে। এই শব্দার্থবিজ্ঞানের প্রতি শ্রদ্ধা জানাতে, অপ্টিমাইজার এমন একটি পরিকল্পনা তৈরি করে যা পাস-থ্রু পূর্বাভাস ব্যবহার করে:
নেস্টেড লুপের অভ্যন্তরীণ দিকটি কেবল তখনই মূল্যায়ন করা হয় যখন পাস-থ্রো ফিডিকেট মিথ্যা দেয় returns সামগ্রিক প্রভাবটি হ'ল CASE
এক্সপ্রেশনগুলি ক্রমে পরীক্ষা করা হয় এবং পূর্ববর্তী কোনও এক্সপ্রেশন সন্তুষ্ট না হলে কেবল সাবকুইরিগুলি মূল্যায়ন করা হয়।
একটি উপস্থিতি subquery সঙ্গে CASE এক্সপ্রেশন
যেখানে একটি CASE
সাবকিউরি ব্যবহার করে EXISTS
, লজিকাল অস্তিত্ব পরীক্ষাটি একটি আধা-যোগ হিসাবে প্রয়োগ করা হয়, তবে পরের ধারাটির প্রয়োজন হলে সেমিগুলি সাধারণত আধা-যুক্ত দ্বারা প্রত্যাখ্যান করা হবে r এই বিশেষ ধরণের আধা-যুক্তের মধ্য দিয়ে প্রবাহিত সারিগুলি একটি অর্ধ-যোগটি মিল খুঁজে পেয়েছে কিনা তা চিহ্নিত করার জন্য একটি পতাকা অর্জন করে। এই পতাকাটি প্রোব কলাম হিসাবে পরিচিত ।
বাস্তবায়নের বিশদটি হ'ল লজিকাল সাবকোয়ারিটি একটি প্রোলে কলামের সাথে একটি 'রিলেটেড জোড়' ('প্রয়োগ') দ্বারা প্রতিস্থাপিত হয়। কাজটি কোয়েরি অপ্টিমাইজার নামে একটি সরলীকরণ নিয়ম দ্বারা সম্পাদিত হয় RemoveSubqInPrj
(প্রজেক্টে সাবকোয়ারিটি সরিয়ে দিন)। আমরা ট্রেস পতাকা 8606 ব্যবহার করে বিশদটি দেখতে পাচ্ছি:
SELECT
T1.ID,
CASE
WHEN EXISTS
(
SELECT 1
FROM #T2 AS T2
WHERE T2.ID = T1.ID
) THEN 1
ELSE 0
END AS DoesExist
FROM #T1 AS T1
WHERE T1.ID BETWEEN 5000 AND 7000
OPTION (QUERYTRACEON 3604, QUERYTRACEON 8606);
EXISTS
পরীক্ষা দেখানো ইনপুট ট্রিটির কিছু অংশ নীচে দেখানো হয়েছে:
ScaOp_Exists
LogOp_Project
LogOp_Select
LogOp_Get TBL: #T2
ScaOp_Comp x_cmpEq
ScaOp_Identifier [T2].ID
ScaOp_Identifier [T1].ID
এটি দ্বারা RemoveSubqInPrj
নেতৃত্বাধীন কাঠামোয় রূপান্তরিত হয়:
LogOp_Apply (x_jtLeftSemi probe PROBE:COL: Expr1008)
এটি পূর্বে বর্ণিত তদন্তের সাথে বাম আধা-যুক্ত হবে। এই প্রাথমিক রূপান্তরটি এখন পর্যন্ত এসকিউএল সার্ভারের ক্যোয়ারী অপ্টিমাইজারগুলিতে একমাত্র উপলভ্য, এবং এই রূপান্তরটি অক্ষম থাকলে সংকলনটি কেবল ব্যর্থ হবে।
এই ক্যোয়ারির জন্য কার্যকর কার্যকর পরিকল্পনার আকারগুলির মধ্যে একটি হ'ল লজিকাল স্ট্রাকচারের প্রত্যক্ষ বাস্তবায়ন:
চূড়ান্ত গণনা স্কেলার CASE
প্রোব কলাম মান ব্যবহার করে প্রকাশের ফলাফলটি মূল্যায়ন করে :
যখন প্ল্যান ট্রি গাছের মূল আকৃতিটি সংরক্ষণ করা হয় যখন অপ্টিমাইজ করা হয় অন্যান্য শারীরিক যোগদানের প্রকারগুলি অর্ধ জোড়ার জন্য বিবেচনা করে। কেবল মার্জ জয় একটি প্রোব কলাম সমর্থন করে, সুতরাং একটি হ্যাশ আধা যোগদান, যদিও যুক্তিযুক্তভাবে সম্ভব, বিবেচনা করা হয় না:
মার্জটি লেবেলযুক্ত একটি অভিব্যক্তি আউটপুটগুলি লক্ষ্য করুন Expr1008
(যে নামটি পূর্বের মতো একটি কাকতালীয়) তবে পরিকল্পনার কোনও অপারেটরের জন্য এর জন্য কোনও সংজ্ঞা প্রদর্শিত হয়নি। এটি আবার প্রোবের কলাম। আগের মতো, চূড়ান্ত গণনা স্কেলারটি মূল্যায়ন করতে এই প্রোব মানটি ব্যবহার করে CASE
।
সমস্যাটি হ'ল অপটিমাইজার সম্পূর্ণরূপে এমন বিকল্পগুলি অন্বেষণ করে না যা কেবল মার্জ (বা হ্যাশ) আধা যোগদানের সাথে সার্থক হয়। নেস্টেড লুপস পরিকল্পনায়, T2
প্রতিটি পুনরাবৃত্তির সাথে সারি সারি মিলছে কিনা তা খতিয়ে দেখার কোনও সুবিধা নেই । মার্জ বা হ্যাশ পরিকল্পনার সাথে, এটি একটি দরকারী অপ্টিমাইজেশন হতে পারে।
যদি আমরা ক্যোয়ারিতে কোনও মিলের BETWEEN
শিকারী যুক্ত করি, তবে T2
যা ঘটে তা হ'ল এই চেকটি প্রতিটি সারিটির জন্য মার্জ সেমি জয়েন্টের অবশিষ্টাংশ হিসাবে সম্পাদন করা হয় (কার্যকর করার পরিকল্পনায় স্পষ্ট হওয়া শক্ত, তবে এটি রয়েছে):
SELECT
T1.ID,
CASE
WHEN EXISTS
(
SELECT 1
FROM #T2 AS T2
WHERE T2.ID = T1.ID
AND T2.ID BETWEEN 5000 AND 7000 -- New
) THEN 1
ELSE 0
END AS DoesExist
FROM #T1 AS T1
WHERE T1.ID BETWEEN 5000 AND 7000;
আমরা আশা করবো যে BETWEEN
শিকারী পরিবর্তনের পরিবর্তে একটি সন্ধানের T2
ফলস্বরূপ নিচে নামানো হবে । সাধারণত, অপ্টিমাইজার এটি করার বিষয়ে বিবেচনা করবে (এমনকি কোয়েরিতে অতিরিক্ত শিকারী নাও)। এটা তোলে স্বীকার উহ্য predicates ( BETWEEN
উপর T1
এবং তাদের মধ্যে সম্পৃক্ত যোগদানের T1
এবং T2
একসঙ্গে পরোক্ষভাবে BETWEEN
উপর T2
) ছাড়াই মূল প্রশ্নের সাথে টেক্সট উপস্থিত হচ্ছে। দুর্ভাগ্যক্রমে, প্রয়োগ-প্রোব প্যাটার্নটির অর্থ এটি অন্বেষণ করা হয়নি।
উভয় ইনপুটগুলিতে একত্রিত হয়ে যাওয়া সেমিতে যোগদানের জন্য সিকিউরিটি লেখার জন্য কোয়েরি লেখার উপায় রয়েছে। একটি উপায়ে ক্যুরিয়ারটি বেশ অপ্রাকৃতভাবে লিখতে জড়িত (আমি সাধারণত যে কারণে পছন্দ করি তা পরাস্ত করে EXISTS
):
WITH T2 AS
(
SELECT TOP (9223372036854775807) *
FROM #T2 AS T2
WHERE ID BETWEEN 5000 AND 7000
)
SELECT
T1.ID,
DoesExist =
CASE
WHEN EXISTS
(
SELECT * FROM T2
WHERE T2.ID = T1.ID
) THEN 1 ELSE 0 END
FROM #T1 AS T1
WHERE T1.ID BETWEEN 5000 AND 7000;
উত্পাদনের পরিবেশে সেই ক্যোয়ারীটি লিখতে আমি খুশি হব না, এটি কেবল প্রদর্শন করা যে কাঙ্ক্ষিত পরিকল্পনার আকার সম্ভব। সত্যিকারের ক্যোয়ারীটি যদি আপনাকে CASE
এই নির্দিষ্টভাবে ব্যবহার করতে হয় এবং পারফরম্যান্সের ফলে কোনও একত্রিত হওয়া আধা-যোগদানের তদন্তের পক্ষের অনুসন্ধান না করা হয়, তবে আপনি সঠিক বাক্য তৈরি করে এমন বিভিন্ন বাক্য গঠন ব্যবহার করে কোয়েরিটি লিখতে বিবেচনা করতে পারেন আরও কার্যকর কার্যকর পরিকল্পনা।