বাম যোগদান বা না থাকা ব্যবহারের মধ্যে সেরা অনুশীলন


67

বাম যোগদান বা একটি বিদ্যমান না ফর্ম্যাট ব্যবহার করার মধ্যে কি সেরা অনুশীলন আছে?

একে অপরকে ব্যবহার করে কী লাভ?

যদি না হয় তবে কোনটি পছন্দ করা উচিত?

SELECT *
FROM tableA A
LEFT JOIN tableB B
     ON A.idx = B.idx
WHERE B.idx IS NULL

SELECT *
FROM tableA A
WHERE NOT EXISTS
(SELECT idx FROM tableB B WHERE B.idx = A.idx)

আমি কোনও এসকিউএল সার্ভার ডাটাবেসের বিপরীতে অ্যাক্সেসের মধ্যে প্রশ্নগুলি ব্যবহার করছি।


2
একটি সরাইয়া হিসাবে, আপাতদৃষ্টিতে-অভিন্ন পদ্ধতির WHERE A.idx NOT IN (...) হয় না অভিন্ন এর trivalent আচরণ কারণে NULL(যেমন NULLসমান নয় NULL, (কিংবা অসম) অতএব যদি আপনি কোন NULL সালে tableBআপনি অপ্রত্যাশিত ফলাফল পেতে হবে!)
Elaskanator

উত্তর:


58

সর্বাধিক পার্থক্য হ'ল যোগে বনাম উপস্থিত নেই, এটি (লিখিত), এটি SELECT *

প্রথম উদাহরণে, আপনি উভয় থেকে সমস্ত কলাম পান Aএবং Bদ্বিতীয় উদাহরণে আপনি কেবল কলামগুলি পান A

এসকিউএল সার্ভারে, দ্বিতীয় রূপটি খুব সাধারণ একটি নিয়মিত উদাহরণে কিছুটা দ্রুত:

দুটি নমুনা সারণী তৈরি করুন:

CREATE TABLE dbo.A
(
    A_ID INT NOT NULL
        PRIMARY KEY CLUSTERED
        IDENTITY(1,1)
);

CREATE TABLE dbo.B
(
    B_ID INT NOT NULL
        PRIMARY KEY CLUSTERED
        IDENTITY(1,1)
);
GO

প্রতিটি সারণীতে 10,000 সারি sertোকান:

INSERT INTO dbo.A DEFAULT VALUES;
GO 10000

INSERT INTO dbo.B DEFAULT VALUES;
GO 10000

দ্বিতীয় সারণী থেকে প্রতি 5 তম সারিতে সরান:

DELETE 
FROM dbo.B 
WHERE B_ID % 5 = 1;

SELECT COUNT(*) -- shows 10,000
FROM dbo.A;

SELECT COUNT(*) -- shows  8,000
FROM dbo.B;

দুটি পরীক্ষার SELECTবিবৃতি বৈকল্পিকগুলি সম্পাদন করুন :

SELECT *
FROM dbo.A
    LEFT JOIN dbo.B ON A.A_ID = B.B_ID
WHERE B.B_ID IS NULL;

SELECT *
FROM dbo.A
WHERE NOT EXISTS (SELECT 1
    FROM dbo.B
    WHERE b.B_ID = a.A_ID);

কার্যকর করার পরিকল্পনা:

এখানে চিত্র বর্ণনা লিখুন

দ্বিতীয় বৈকল্পিকটি ফিল্টার অপারেশন করার প্রয়োজন হয় না কারণ এটি বাম অ্যান্টি-সেমি জয়েন্ট অপারেটরটি ব্যবহার করতে পারে।


23

NOT EXISTSযৌক্তিকভাবে সেগুলি অভিন্ন, তবে আপনি যে অ্যান্টিসেমিওজিনের জন্য জিজ্ঞাসা করছেন তার কাছাকাছি এবং সাধারণত পছন্দ হয়। এটি আরও ভালভাবে হাইলাইট করে যে আপনি বি তে কলামগুলি অ্যাক্সেস করতে পারবেন না, কারণ এটি কেবলমাত্র একটি ফিল্টার হিসাবে ব্যবহৃত হয় (সেগুলি NULL মান সহ উপলব্ধ করার বিপরীতে)।

বহু বছর আগে (এসকিউএল সার্ভার .0.০ ইশ) LEFT JOINদ্রুত ছিল, তবে এটি খুব দীর্ঘ সময়ের জন্য হয়নি। আজকাল, NOT EXISTSসামান্য দ্রুত।


অ্যাক্সেসের সবচেয়ে বড় প্রভাবটি হ'ল JOINপদ্ধতিটি ফিল্টার করার আগে যোগদানটি সম্পূর্ণ করতে হবে, মেমরিতে যুক্ত সেটটি তৈরি করে। ব্যবহার NOT EXISTSসারি পরীক্ষা কিন্তু কলামের জন্য স্থান বরাদ্দ নেই। এছাড়াও, এটি একবার সারি পেলে তা দেখতে থামে। অ্যাক্সেসে পারফরম্যান্স কিছুটা আলাদা হয় তবে থাম্বের একটি সাধারণ নিয়ম হ'ল NOT EXISTSকিছুটা দ্রুত be আরও বেশি কারণের সাথে জড়িত থাকায় আমি এটি "সেরা অনুশীলন" বলতে কম ঝোঁক হব।


6

লিংকড সার্ভারগুলি ব্যবহার NOT EXISTSকরার LEFT JOIN ... WHERE IS NULLসময় আমি যে ব্যতিক্রমটি লক্ষ্য করেছি তার চেয়ে সেরা (তবে প্রান্তিক) ।

মৃত্যুদণ্ড কার্যকর করার পরিকল্পনাগুলি পরীক্ষা করে দেখা যায় যে NOT EXISTSঅপারেটর নেস্টেড লুপ ফ্যাশনে মৃত্যুদন্ড কার্যকর করেছেন। যার মাধ্যমে এটি প্রতি সারির ভিত্তিতে কার্যকর করা হয় (যা আমি মনে করি এটি বোধগম্য)।

উদাহরণস্বরূপ কার্যকর করার পরিকল্পনা এই আচরণটি দেখায়: এখানে চিত্র বর্ণনা লিখুন


1
লিঙ্কযুক্ত সার্ভারগুলি এই জাতীয় জিনিসটির জন্য নির্মম। সমস্যাটি সমাধানের একটি সম্ভাব্য পন্থা হ'ল সংযুক্ত সার্ভারের লিঙ্কের মাধ্যমে রিমোট ডেটাটি অনুলিপি করে একটি সহজ ব্যবহার করে ডাটাবেসের সেই অস্থায়ী অনুলিপিটির বিরুদ্ধে ধারাটি INSERT INTO #t (a,b,c) SELECT a,b,c FROM LinkedServer.database.dbo.table WHERE x=yচালানো NOT EXISTS (...)
ম্যাক্স ভার্নন

2
আমার পোস্টে ম্যাক্স ভার্ননের কাছ থেকে প্রতিক্রিয়া পেতে এখনই একটু বাষ্পাল! ফ্যানবয়'ই একপাশে। আপনি যে মজার কথাটি উল্লেখ করেছেন তা মজার বিষয়, কারণ আমি ক্রস-সার্ভারের পরিস্থিতি থেকে সর্বাধিক সুবিধা অর্জন করতে বেশ কয়েকটি উপলক্ষে সেই সঠিক পদ্ধতির ব্যবহার করেছি।
রোবপিম

1
চিয়ার্স, @ পিমব্রুউবার্স - আপনার মতামতী মন্তব্যের জন্য ধন্যবাদ!
ম্যাক্স ভার্নন

5

সাধারণভাবে, ইঞ্জিন মূলত উপর ভিত্তি করে একটি কার্যকরকরণ পরিকল্পনা তৈরি করবে:

  1. A এবং B তে সারি সংখ্যা
  2. এ এবং / বা বিতে কোনও সূচক রয়েছে কিনা
  3. ফলাফলের সারিগুলির প্রত্যাশিত সংখ্যা (এবং মধ্যবর্তী সারিগুলি)
  4. ইনপুট ক্যোয়ারির ফর্ম (যেমন আপনার প্রশ্ন)

(4) এর জন্য:

"বিদ্যমান নেই" পরিকল্পনাটি টেবিল বি-তে একটি চাওয়া ভিত্তিক পরিকল্পনাকে উত্সাহিত করে যখন টেবিল এ ছোট হয় এবং টেবিল বি বড় হয় (এবং বিতে একটি সূচক বিদ্যমান থাকে) এটি ভাল পছন্দ।

"অ্যান্টিজয়িন" পরিকল্পনাটি একটি ভাল পছন্দ যখন টেবিল এ খুব বড় হয় বা টেবিল বি খুব ছোট হয় বা বি তে কোনও সূচক না থাকে এবং একটি বড় ফলাফলের সেটটি ফেরত দেয়।

তবে এটি কেবল একটি "উত্সাহ", যেমন ভারী ইনপুট। একটি শক্তিশালী (1), (2), (3) প্রায়শই (4) শব্দের জন্য পছন্দ করে।

(@ ম্যাক্স ভার্নন উত্তর দ্বারা সম্বোধিত * এর কারণে বিভিন্ন কলাম ফিরিয়ে দেওয়া আপনার উদাহরণের প্রভাব উপেক্ষা করে))।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.