যোগদান বা WHERE এর মধ্যে শর্ত


192

JOIN ক্লজ বনাম কোথাও একটি শর্ত স্থাপনের মধ্যে কোনও পার্থক্য রয়েছে (পারফরম্যান্স, সেরা অনুশীলন, ইত্যাদি ...)?

উদাহরণ স্বরূপ...

-- Condition in JOIN
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
AND CUS.FirstName = 'John'

-- Condition in WHERE
SELECT *
FROM dbo.Customers AS CUS
INNER JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE CUS.FirstName = 'John'

আপনি কোনটি পছন্দ করেন (এবং সম্ভবত কেন)?


4
আপনি কি দুটি প্রশ্ন চালিয়েছেন? আপনি দুটি প্রশ্নের দ্বারা উত্পাদিত কার্যকরকরণ পরিকল্পনাগুলি পরীক্ষা করে দেখেছেন? আপনি কি পালন করেছেন?
এস .লট

21
@ এস.লট, এই ক্যোয়ারী কেবল উদাহরণস্বরূপ। আমি কেবল "সাধারণভাবে" ভাবছি যা পছন্দসই পদ্ধতি - যদি কোনও হয়।
স্টিভ ডিগানান

1
@ স্টিভ ডিগানান: আপনার এটি নমুনা ডেটা সহ বেঞ্চমার্ক করা উচিত এবং ক্যোয়ারী পরিকল্পনাগুলি লক্ষ্য করা উচিত। উত্তরটি খুব, খুব স্পষ্ট হবে। এবং - বোনাস - আরও জটিল পরিস্থিতি দেখা দিলে আপনার পুনরায় ব্যবহার করতে পারেন এমন একটি কোডের টুকরো থাকবে।
এসলট

1
শর্তটি সম্পর্কের বর্ণনা দিলে আমি ব্যক্তিগতভাবে শর্তটি জোয়িন ক্লজে রেখে দেব। জেনেরিক শর্তাবলী যা কেবলমাত্র ফলাফল সেট ফিল্টার করে তারপরে যেখানে পুরো অংশে যাবে। উদাহরণস্বরূপFROM Orders JOIN OrderParties ON Orders.Id = OrderParties.Order AND OrderParties.Type = 'Recipient' WHERE Orders.Status = 'Canceled'
গ্লিউটেক্সো

উত্তর:


153

রিলেশনাল বীজগণিত predicates এর interchangeability পারবেন WHEREদফা এবং INNER JOIN, তাই এমনকি INNER JOINকোয়েরি নিয়ে WHEREক্লজ predicates অপটিমাইজার যাতে তারা দ্বারা rearrranged থাকতে পারে ইতিমধ্যে বাদ দেওয়া হতে পারে সময় JOINপ্রক্রিয়া।

আমি আপনাকে সর্বাধিক পঠনযোগ্য উপায়ে প্রশ্নগুলি লেখার পরামর্শ দিচ্ছি।

কখনও কখনও এর মধ্যে INNER JOINতুলনামূলকভাবে "অসম্পূর্ণ" করা এবং WHEREফিল্টারিং মানদণ্ডগুলির তালিকা আরও সহজে বজায় রাখা যায় এমন জন্য কিছু মানদণ্ডকে সহজভাবে অন্তর্ভুক্ত করা অন্তর্ভুক্ত।

উদাহরণস্বরূপ, পরিবর্তে:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

লিখুন:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

তবে এটি অবশ্যই নির্ভর করে।


7
এটি কেবল পরিষ্কার ক্যোয়ারী বা পঠনযোগ্যতা সম্পর্কে নয়, এটি কর্মক্ষমতা সম্পর্কে। শর্তগুলিতে যোগ দেওয়ার সাথে সাথে সঠিকভাবে ইনডেক্সযুক্ত টেবিলগুলি সহ প্রচুর পরিমাণে ডেটার জন্য কর্মক্ষমতা উন্নত করে।
শাহাদাত

1
আমি কয়েক মিলিয়ন রেকর্ডে মাত্র 5-6 টেবিলগুলিতে যোগদানের জন্য মাসিক বিক্রয় প্রতিবেদনগুলি চালাচ্ছি। পার্ফ 30% দ্বারা বর্ধিত - এসকিউএল সার্ভার 2012
শাহদাত

2
@ শাহাদাত যদি আপনি সেই কার্যকর পারফরম্যান্সের পার্থক্য পেয়ে থাকেন যা আপনার ফিল্টার শর্তগুলি স্থান থেকে অভ্যন্তরীণ অংশে সরিয়ে নিয়ে যায় তবে আপনাকে সেই কার্যকর করার পরিকল্পনা পোস্ট করতে হবে।
ক্যাড রক্স

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

4
এই উত্তরটি INNER যোগদানের জন্য সঠিক তবে বাম / ডান যোগদানের জন্য নয়।
সটন

121

অভ্যন্তরীণ যোগদানের জন্য আমি সত্যই কোনও পার্থক্য লক্ষ্য করিনি (তবে সমস্ত পারফরম্যান্স টিউন করার সাথে সাথে আপনার অবস্থার অধীনে আপনার ডাটাবেসের বিরুদ্ধে পরীক্ষা করা দরকার)।

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

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE ORD.OrderDate >'20090515'

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
AND ORD.OrderDate >'20090515'

প্রথমটি আপনাকে কেবল সেই রেকর্ড দেবে যা 15 ই মে, ২০০৯ এর পরে তারিখের পরে অর্ডার দিয়েছে যাতে বাম জোড়াকে অভ্যন্তরীণ যোগে রূপান্তরিত করে। দ্বিতীয়টি সেই রেকর্ডগুলি এবং কোনও অর্ডার ছাড়া কোনও গ্রাহককে দেবে। আপনি শর্তটি কোথায় রেখেছেন তার উপর নির্ভর করে ফলাফল সেটগুলি খুব আলাদা। (উদাহরণস্বরূপ কেবলমাত্র উদাহরণস্বরূপ, * নির্বাচন করুন * আপনার অবশ্যই উত্পাদন কোডে অবশ্যই ব্যবহার করা উচিত নয় this) এর ব্যতিক্রমটি যখন আপনি কেবল একটি টেবিলে কেবল রেকর্ড দেখতে চান তবে অন্যটি নয়। তারপরে আপনি শর্তটির জন্য যেখানে ক্লজটি ব্যবহার করবেন তা যোগ না দিয়ে।

SELECT *
FROM dbo.Customers AS CUS 
LEFT JOIN dbo.Orders AS ORD 
ON CUS.CustomerID = ORD.CustomerID
WHERE ORD.OrderID is null

উদাহরণ সহকারে ব্যাখ্যা করার জন্য ধন্যবাদ
রেনিশ জোসেফ

1
"এইভাবে বাম জোড়াকে একটি অভ্যন্তরীণ জোড়ায় রূপান্তর করা"। কিভাবে? আপনি কিছুটা ব্যাখ্যা করতে পারেন?
user1451111

@ user1451111 কী বাম / ডান জোনে ফিরে আসে তা শিখুন: অভ্যন্তরীণ সারি যুক্ত করুন এবং ন্যূনতম দ্বারা বর্ধিত / ডান টেবিল সারিগুলিতে মিলিত হবে। সম্পূর্ণ যোগদান করে UNNLs দ্বারা বর্ধিত সমস্ত ডাবল টেবিল সারি মিলবে না সমস্ত ইউনিয়ন মিলকে সারি যুক্ত করে returns একটি বাহ্যিক যোগদানের অংশ হিসাবে আপনি কী অভ্যন্তরীণ যোগদান করতে চান তা সর্বদা জানুন। একটি যেখানে বা তার বাইরে সম্ভবত যোগদানের পরে নুল না হওয়ার জন্য সম্ভবত নুল-প্রসারিত কলামের দরকার পড়ে, নুল দ্বারা প্রসারিত যে কোনও সারি অপসারণ করে, যার ফলে কেবলমাত্র অভ্যন্তরীণ সারিগুলি ছেড়ে যায়, অর্থাত্ "আউটর জয়েনকে একটি অন্তর্ভুক্ত যোগদান করে"।
ফিলিপ্সি

1
@ ব্যবহারকারী1451111 বা, সহজ ভাষায়: A left join Bএ থেকে প্রতিটি সারি বি থেকে প্রাপ্ত প্রতিটি মিলের সারিতে যোগ হয়েছে, যদি বি এর কোনও সারি মেলে না, তবে এ কলামের বি এর প্রতিটি কলামের মান আছে তবে সেই সারির B এর প্রতিটি কলামই NULL মান হিসাবে দেখায়। আপনি যদি লিখে থাকেন where B.somecolumn = ‘somevalue’তবে আপনার কোনও 'এনওএলএল' (বিসোমাকলম) 'কিছুটা' এর সাথে তুলনা করা হচ্ছে। NUL এর সাথে তুলনা করা যে কোনও কিছুই মিথ্যা, সুতরাং আপনার সমস্ত সারি যেখানে A সারিটির সাথে কোনও মিল নেই বি সারি, অপসারণ করা হবে এবং ফলাফল আপনি যে কোনও অভ্যন্তরীণ যোগ দিয়েছিলেন তার সমান, তাই বাহ্যিক যোগটি অভ্যন্তরীণ হয়ে গেছে
Caius Jard

হ্যাঁ আমি যাচাই করেছি ফলাফলগুলি এর জন্য একই: সিলেক্ট ফান্ডস.আইডি, প্রসপেক্টস.আইডি থেকে fundsঅভ্যন্তরীণ যোগদানের সম্ভাবনাগুলি (প্রসপেক্ট.আইডি = ফান্ডসিলিডি_আইডি এবং প্রসপেক্টস.আইস_মানুয়াল = 'না') এবং ফান্ডস.আইডি, প্রসপেক্টস.আইডি থেকে fundsছেড়ে (প্রসপেক্টস.আইডি = ফিডস.এলডি_আইডি) তে সম্ভাবনাগুলি যোগ দিন যেখানে সম্ভাবনা.আইস_মানুয়াল = 'না'
রোহিত ধীমান

25

বেশিরভাগ আরডিবিএমএস পণ্য একইভাবে উভয় প্রশ্নের অনুকূলিত করে। পিটার গুলুতজান এবং ট্রুডি পেলজারের "এসকিউএল পারফরম্যান্স টিউনিং" -তে তারা একাধিক ব্র্যান্ড আরডিবিএমএস পরীক্ষা করেছে এবং কোনও পারফরম্যান্সের পার্থক্য খুঁজে পায় নি।

আমি যোগ শর্তগুলি ক্যোয়ারের সীমাবদ্ধতার শর্ত থেকে আলাদা রাখতে পছন্দ করি।

আপনি যদি OUTER JOINমাঝে মাঝে ব্যবহার করেন তবে যোগদানের শর্তে শর্ত রাখা দরকার।


1
আমি আপনার সাথে একমত হই যে সিন্ট্যাক্টিকভাবে এটি ক্লিনার, এবং আমাকে সেই বইটি এবং আপনার খুব উচ্চ খ্যাতি সম্পর্কে আপনার জ্ঞান স্থগিত করতে হবে, তবে আমি গত সপ্তাহে 4 টি ক্যোয়ারী সম্পর্কে খুব আলাদা এক্সিকিউশন প্ল্যান, সিপিইউ বার এবং লজিকাল রিডের সাথে ভাবতে পারি আমি যোগদানের পূর্বাভাস যেখানে সরানো হয়েছে।
marr75

2
আপনি সেরা অনুশীলন সম্পর্কে জিজ্ঞাসা ছিল। কোনও নির্দিষ্ট আরডিবিএমএস বাস্তবায়ন কীভাবে কাজ করে তা পরীক্ষা করে নেওয়ার সাথে সাথেই অন্যান্য লোকেরা সঠিক পরামর্শটি দিয়েছেন: বেঞ্চমার্ক।
বিল কারভিন

12

যোগদানের পরে যেখানে ফিল্টার হবে।

JOIN প্রক্রিয়া চলাকালীন সারিগুলি যুক্ত হতে আটকাতে JOIN এ ফিল্টার করুন।


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

1
ক্যাড রক্স: ঠিক আছে। প্রায়শই আপনি এসকিউএল-এ যা লেখেন তা যখন না বলা হয় তখন সবই করা হয়ে গেলে অপ্টিমাইজার আপনাকে দেয়। আমি তখন মনে করব যে এটি সর্ব-তত্ত্বের বিশ্বে সঠিক হবে, যদিও আপনার উত্তরটি স্বয়ংক্রিয়ভাবে ক্যোয়ারী অপ্টিমাইজারের বিশ্বে আরও সঠিক রয়েছে :)
TheTXI

শর্তটির এই ব্যাখ্যাটি আমার পছন্দON
রবার্ট রোচা

3

আমি পূর্ণ টেবিল / দর্শনগুলিতে যোগদানের জন্য জিনকে অগ্রাধিকার দেব এবং তারপরে ফলাফলের সেটটির প্রাকটিকটি প্রবর্তন করতে WHERE ব্যবহার করব।

এটি সিনট্যাক্টিক্যালি ক্লিনার অনুভূত হয়।


2

আমি সাধারণত যোগদানের ফিল্টার করার সময় পারফরম্যান্স বাড়তে দেখি। বিশেষত যদি আপনি উভয় টেবিলের জন্য সূচকযুক্ত কলামগুলিতে যোগ দিতে পারেন। লজিকাল রিডগুলি আপনার বেশিরভাগ ক্যোরির সাথে এটি করার চেষ্টা করা উচিত, যা উচ্চ ভলিউমের পরিবেশে কার্যকর হওয়ার সময়টির চেয়ে আরও ভাল পারফরম্যান্স সূচক।

যখন কেউ তাদের এসকিউএল বেঞ্চমার্কিং দেখায় আমি সর্বদা মৃদু আচ্ছন্ন হয়ে থাকি এবং তারা ডেভ সার্ভারে মধ্যরাতে 50,000 বার স্প্রোকের উভয় সংস্করণ কার্যকর করে এবং গড় সময়ের তুলনা করে।


0

যোগদানের শর্তটি রাখা আমার কাছে "শব্দার্থগতভাবে ভুল" বলে মনে হয়, কারণ এটি জিনস "পক্ষে" নয়। তবে এটি খুব গুণগত।

অতিরিক্ত সমস্যা: আপনি যদি অভ্যন্তরীণ যোগদান থেকে স্যুইচ করার সিদ্ধান্ত নেন, বলুন, ডান যোগ দিন, শর্তটি JOIN এর মধ্যে থাকার ফলে অপ্রত্যাশিত ফলাফল হতে পারে।


3
কখনও কখনও এই ফলাফলগুলি "প্রত্যাশিত" এবং কখনও কখনও "ইচ্ছাকৃত "ও হয় (উদাহরণস্বরূপ বাইরের সাথে যোগ দেয় যেখানে যেখানে শর্তের সাথে জিন শর্তের চেয়ে আলাদা শব্দার্থবিজ্ঞান রয়েছে)।
মার্সেল টথ

0

আপনার কাছে যখন বড় টেবিল থাকে তখন আমার মতে দ্রুত যোগদান হয়। এটি আসলে কোনও তাত্পর্যপূর্ণ নয় যদিও বিশেষত যদি আপনি বরং একটি ছোট টেবিল নিয়ে কাজ করছেন। যখন আমি প্রথম যোগদানের বিষয়ে জানতে পেরেছিলাম, আমাকে জানানো হয়েছিল যে শৃঙ্খলাগুলি শৃঙ্খলার সাথে মিলিত হওয়ার মতো অবস্থা যেখানে শর্ত শর্ত রয়েছে এবং আমি যদি সেগুলি শর্তটি কোন করণীয় সম্পর্কে সুনির্দিষ্ট করে থাকি তবে আমি সেগুলি পরস্পর পরিবর্তে ব্যবহার করতে পারতাম।


-4

যুক্ত হওয়ার শর্তটি যুক্ত করা ভাল। পারফরম্যান্স পাঠযোগ্যতার চেয়ে গুরুত্বপূর্ণ is বড় ডেটাসেটগুলির জন্য, এটি গুরুত্বপূর্ণ।


1
আপনার কাছে কি কোনও প্রমান রয়েছে, গবেষণাটি কীভাবে উল্লিখিত পূর্বাভাসগুলির স্থান কার্যকারিতাকে প্রভাবিত করে?
Zso
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.