কোনও অন্তঃসত্ত্বা অবস্থায় 'বা' থাকা কি খারাপ ধারণা?


96

অসীম ধীর ক্যোয়ারির গতি উন্নত করার চেষ্টা করার জন্য ( এসকিউএল সার্ভার ২০০৮-তে প্রতিটি table 50,000 সারি দিয়ে দুটি টেবিলের কয়েক মিনিট ) যদি এটি বিবেচনা করে তবে, আমি ORআমার অভ্যন্তরীণ যোগদানের ক্ষেত্রে সমস্যাটি সংকুচিত করেছিলাম , যেমন:

SELECT mt.ID, mt.ParentID, ot.MasterID
  FROM dbo.MainTable AS mt
  INNER JOIN dbo.OtherTable AS ot ON ot.ParentID = mt.ID
                                  OR ot.ID = mt.ParentID

আমি এটিকে (যা আমি প্রত্যাশা করি) এটিকে এখানে বাম সংখ্যার সমতুল্য জোড় যোগদান করে:

SELECT mt.ID, mt.ParentID,
   CASE WHEN ot1.MasterID IS NOT NULL THEN
      ot1.MasterID ELSE
      ot2.MasterID END AS MasterID
  FROM dbo.MainTable AS mt
  LEFT JOIN dbo.OtherTable AS ot1 ON ot1.ParentID = mt.ID
  LEFT JOIN dbo.OtherTable AS ot2 ON ot2.ID = mt.ParentID
  WHERE ot1.MasterID IS NOT NULL OR ot2.MasterID IS NOT NULL

.. এবং ক্যোয়ারী এখন প্রায় এক সেকেন্ডে চলে!

ORযোগদানের শর্তে যুক্ত করা কি সাধারণত খারাপ ধারণা ? অথবা আমি আমার টেবিলগুলির বিন্যাসে কোনওভাবেই দুর্ভাগ্য?


6
আপনার প্রশ্নের পরিবর্তে আমাদের কার্যকর করার পরিকল্পনাটি দেখান।
অন্ধ

একটি অদ্ভুত সম্পর্কের মতো বলে মনে হচ্ছে
নাথন গঞ্জালেজ

@ ব্লিন্ডি: ভাল ধারণা। এটি বাস্তবায়নের পরিকল্পনাগুলিতে দেখা যাচ্ছে যে কাসনসুই নীচে কী উল্লেখ করেছেন: প্রথম কোয়েরি নেস্টেড লুপগুলিতে আসে, যখন দ্বিতীয়টি হ্যাশ যোগ দিয়ে সম্পন্ন হয়।
লাড্ডেজ

উত্তর:


115

এই ধরণের JOINএকটি HASH JOINবা a এর জন্য অনুকূল নয় MERGE JOIN

এটি দুটি ফলাফলের ফলাফলের সমাহার হিসাবে প্রকাশ করা যেতে পারে:

SELECT  *
FROM    maintable m
JOIN    othertable o
ON      o.parentId = m.id
UNION
SELECT  *
FROM    maintable m
JOIN    othertable o
ON      o.id = m.parentId

, তাদের প্রত্যেকেরই একটি ইক্যুইজিন হওয়া সত্ত্বেও, SQL Serverএর অপ্টিমাইজারটি আপনার লেখা ক্যোয়ারিতে এটি দেখতে যথেষ্ট স্মার্ট নয় (যদিও তারা যুক্তিযুক্তভাবে সমতুল্য)।


4
এটি উপলব্ধি করে তোলে, আপনাকে ধন্যবাদ। আমি এখনও নিশ্চিত নই যে আমার জিজ্ঞাসা সম্পর্কে অদ্ভুত কিছু আছে কিনা, বা যদি আমাকে কেবল ON w=x OR y=zপুরোপুরি প্যাটার্নটিতে যোগদান করা উচিত ?
লাড্ডেজ

@ ব্লাডেঞ্জ: নেস্টেড লুপে এইগুলি যোগদান করে একটি টেবিল স্ক্যান ব্যবহার করে। আপনার টেবিলগুলি বড় হলে এটি ধীর হয়।
কাসনসুই

শুধু স্পষ্ট করে বলার জন্য, আপনি যখন "এইগুলিতে যোগদান করেন" বলতে চান, আপনি ফর্মের সমস্ত সাথে যুক্ত হন ON w=x OR y=z? (আপনার ধৈর্যের জন্য ধন্যবাদ!)
লাডেজ

4
@ ব্লাডেঞ্জ: অতিরিক্ত শর্ত থাকতে পারে যা SQL Serverবুঝতে সাহায্য করতে পারে যে একটি কনকেন্টেশন দরকার হবে। বলুন, SELECT * FROM othertable WHERE parentId = 1 OR id = 2উভয় ক্ষেত্রকে সূচিযুক্ত করা হলে তাত্ত্বিকভাবে এমন কোনও কিছুই নেই যা লুপে একই জিনিসটি প্রতিরোধ করতে পারে। SQL Serverএই পরিকল্পনাটি বাস্তবে তৈরি করবে কি না তা অনেকগুলি কারণের উপর নির্ভর করে, তবে আমি বাস্তবে এটি কখনও দেখিনি।
কাসনসুই

আরও মনে রাখবেন যে আপনি যদি জানেন যে তারা সেটগুলি ছিন্নমূল করে রাখে তবে ইউনিয়ন ALL ফলাফল ফলাফলগুলিকে মার্জ করে এড়িয়ে পারফরম্যান্সকে উল্লেখযোগ্যভাবে উন্নত করতে পারে।
ড্যারেন ক্লার্ক

5

আমার পক্ষে কাজ করা শর্ত থেকে আলাদা ফলাফল পেতে আমি নিম্নলিখিত কোডটি ব্যবহার করি।


Select A.column, B.column
FROM TABLE1 A
INNER JOIN
TABLE2 B
ON A.Id = (case when (your condition) then b.Id else (something) END)

-2

পরিবর্তে আপনি ইউনিয়ন সমস্ত ব্যবহার করতে পারেন।

SELECT mt.ID, mt.ParentID, ot.MasterID FROM dbo.MainTable AS mt Union ALL SELECT mt.ID, mt.ParentID, ot.MasterID FROM dbo.OtherTable AS ot


UNION ALLশর্তের JOINসাথে তুলনা করে আপনাকে সদৃশ দেবে OR
কোডমনেকি

সেই জন্য ইউনিয়ন সঠিক হবে। আরো বিস্তারিত জানার জন্য নিম্নলিখিত লিঙ্কে পড়া ইউনিয়ন-এর পরিবর্তে অফ বা
মিটুল Panchal

4
হ্যাঁ তবে আপনার উদাহরণে আপনি এটি লিখেছিলেন union allযা আপনার নিবন্ধের সাথে সংযুক্ত নিবন্ধটিও বর্ণনা হিসাবে সঠিক নয়।
কোডমনেকি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.