ফিল্টারড সূচক কেবল তখনই ব্যবহৃত হয় যখন ফিল্টার করা অংশটি জুড়ে থাকে যেখানে না


10

আমি নীচে ফিল্টারড সূচক তৈরি করেছি যখন আমি 2 টি ক্যুরিয়াকে আরও নিচে চালিয়ে যাই যখন এই সূচকটি কেবল প্রথম দৃষ্টান্তের জন্য অনুসন্ধানের জন্য ব্যবহার করা হবে যেখানে জোনটিতে অধিবেশনটির পরিবর্তে জোনটিতে END_DTTM রয়েছে (প্রশ্নগুলির মধ্যে এটিই পার্থক্য) । কেন এমন হয় তা কেউ ব্যাখ্যা করতে পারেন?

সূচক তৈরি

CREATE NONCLUSTERED INDEX [ix_PATIENT_LIST_BESPOKE_LIST_ID_includes] ON [dbo].[PATIENT_LIST_BESPOKE] 
(
    [LIST_ID] ASC,
    [END_DTTM] ASC
)
WHERE ([END_DTTM] IS NULL)

ক্যোয়ারী

DECLARE @LIST_ID INT = 3655

--This one seeks on the index

SELECT  
    PATIENT_LISTS.LIST_ID
FROM    
    DBO.PATIENT_LISTS
    LEFT JOIN DBO.PATIENT_LIST_BESPOKE ON PATIENT_LISTS.LIST_ID = PATIENT_LIST_BESPOKE.LIST_ID  
                                      AND PATIENT_LIST_BESPOKE.END_DTTM IS NULL
WHERE
    PATIENT_LISTS.LIST_ID = @LIST_ID

--This one scans on the index

SELECT  
    PATIENT_LISTS.LIST_ID
FROM    
    DBO.PATIENT_LISTS
    LEFT JOIN DBO.PATIENT_LIST_BESPOKE ON PATIENT_LISTS.LIST_ID = PATIENT_LIST_BESPOKE.LIST_ID  
WHERE   
    PATIENT_LISTS.LIST_ID = @LIST_ID AND
    PATIENT_LIST_BESPOKE.END_DTTM IS NULL   

উত্তর:


12

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

ব্যাপকভাবে সরল করার জন্য, দৈহিক সূচী কৌশল বাস্তবায়ন এটি করে:

Predicate + Logical Get -> Physical Get (using Index)

আপনার আগ্রহী ক্যোয়ারীটি বাহ্যিক যোগদানের উপরের শিকারী দিয়ে শুরু হয়:

Predicate on T2 --+-- LOJ -- Get (T1)
                       |
                       +---- Get (T2)

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

দ্বিতীয় অংশটি হ'ল অপটিমাইজারের সংরক্ষিত দিকে কোনও বাহ্যিক অতীতকে প্রিন্ট করার জন্য প্রয়োজনীয় অনুসন্ধানের নিয়ম নেই, কারণ রূপান্তরটি খুব কমই বৈধ। এটি অপটিমাইজারের একটি সাধারণ বৈশিষ্ট্য যা কেবলমাত্র প্রায়শই দরকারী নিয়মগুলি প্রয়োগ করা হয়।

ফলস্বরূপ, ফিল্টারড সূচির সাথে ম্যাচ করা ব্যর্থ হয়। স্পষ্টতই, পুনর্লিখনটি আপনার উল্লেখ করা খুব সুনির্দিষ্ট ক্ষেত্রে কার্যকর হবে (দ্বিতীয় ক্যোয়ারী)।

প্রথম ক্যোয়ারী ফর্মের জন্য (বিভিন্ন শব্দার্থবিজ্ঞানের সাথে), প্রেডিকেট শুরু থেকেই যুক্ত হওয়ার সাথে যুক্ত হয়, এবং ভবিষ্যদ্বাণীপূর্ণ পুশ-ডাউন যুক্তিটি সংক্ষিপ্ত দূরত্বটিকে গেটে স্থানান্তরিত করতে পারে কারণ এটি কোনও বাহ্যিক যোগটিকে অতীতের দিকে যেতে না পারায় উপরে বর্ণিত।

পটভূমি এবং আরও তথ্য:


9

এগুলি হল না যেহেতু এক আগে পরে অন্যান্য করতে পারেন ফিল্টার যোগদানের ফিল্টার করতে পারেন শব্দার্থগতভাবে একই প্রশ্নের। আমি একটি সহজ উদাহরণ দিয়ে উদাহরণস্বরূপ:

CREATE TABLE dbo.Lefty(LeftyID INT PRIMARY KEY);

CREATE TABLE dbo.Righty(LeftyID INT, SomeList INT);

INSERT dbo.Lefty(LeftyID) VALUES(1),(2),(3);

INSERT dbo.Righty(LeftyID, SomeList) VALUES(1,1),(1,NULL),(2,2);

ক্যোয়ারী 1 সমস্ত তিনটি সারি প্রদান করে:

SELECT l.LeftyID, r.SomeList
FROM dbo.Lefty AS l
LEFT OUTER JOIN dbo.Righty AS r
ON l.LeftyID = r.LeftyID
AND r.SomeList IS NULL;

প্রশ্ন 2, তবে লেফটআইডি 2 কে ছাড়বে:

SELECT l.LeftyID, r.SomeList
FROM dbo.Lefty AS l
LEFT OUTER JOIN dbo.Righty AS r
ON l.LeftyID = r.LeftyID
WHERE r.SomeList IS NULL;

এসকিউএলফিডাল প্রমাণ

আপনি যদি একটি অ্যান্টি-সেমি জেনার সম্পাদনা করার চেষ্টা করছেন তবে পরীক্ষিত কলামটি বর্ধনযোগ্য নয় । যখন আপনি অন্তর্গতের সাথে কেবলমাত্র যোগ দিচ্ছেন তখনই ও ও WHERE এর মধ্যে মানদণ্ড সরানোর কোনও যৌক্তিক পার্থক্য নেই, তবে আউটারের সাথে একটি উল্লেখযোগ্য পার্থক্য রয়েছে। ফিল্টারড ইনডেক্স এমনকি ব্যবহার করা যায় কি না এর চেয়ে আপনার ফলাফলগুলি সঠিক কিনা সে বিষয়ে আপনার আরও যত্ন নেওয়া উচিত।


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

@ ক্রিস আপনি কি সেই সূচকটিকে একটি সূচক ইঙ্গিত দিয়ে জোর করার চেষ্টা করেছিলেন? আমি সেই ইঙ্গিতটি ছাড়া ও বাস্তবের বাস্তবায়নের পরবর্তী পরিকল্পনাগুলি তুলনা করতে আগ্রহী। আমার কাছে এটি স্পষ্ট যে অপ্টিমাইজার সেই সূচকটিকে উপেক্ষা করছে যখন যখন তারা বিশ্বাস করে যে এটি একটি আধা-বিরোধী জয়েন করছে (যেহেতু এটি ক্ষেত্রে কোনও শ্লথযুক্ত কলামটি ব্যবহার করার আশা করবে না) তবে আমি নিশ্চিত নই যে এটি কিনা ফিল্টারড ইনডেক্সের চেয়ে বাম দিক থেকে সম্ভাব্য অনেকগুলি সারি আসার সম্ভাবনা রয়েছে এমন কিছু ক্রয় বা ক্রিয়াকলাপের অর্ডার বা কিছু অন্তর্নিহিত জ্ঞান দিয়ে করুন। পরিকল্পনাগুলি দেখতে সাহায্য করতে পারে।
অ্যারন বারট্র্যান্ড

3

দুটি প্রশ্ন পৃথক - অর্থ এবং ফলাফলগুলিতে। এখানে একটি পুনরায় লেখা, সুতরাং দুটি ক্যোয়ারী কী করছে তা আরও স্পষ্ট:

-- 1st query
SELECT  
    a.LIST_ID
FROM    
      ( SELECT LIST_ID 
        FROM   DBO.PATIENT_LISTS
        WHERE  LIST_ID = @LIST_ID
      ) AS a
    LEFT JOIN  
      ( SELECT LIST_ID                    -- the filtered index
        FROM   DBO.PATIENT_LIST_BESPOKE   -- can be used
        WHERE  END_DTTM IS NULL           -- for the subquery
      ) AS b
    ON  a.LIST_ID = b.LIST_ID ;           -- and the join

এবং 2 য়:

-- 2nd query
SELECT  
    a.LIST_ID
FROM    
      ( SELECT LIST_ID 
        FROM   DBO.PATIENT_LISTS
        WHERE  LIST_ID = @LIST_ID
      ) AS a
    JOIN  
      ( SELECT LIST_ID                    -- the filtered index
        FROM   DBO.PATIENT_LIST_BESPOKE   -- can be used
        WHERE  END_DTTM IS NULL           -- for the subquery
      ) AS b
    ON  a.LIST_ID = b.LIST_ID             -- and the join

UNION ALL

SELECT  
    a.LIST_ID
FROM    
      ( SELECT LIST_ID 
        FROM   DBO.PATIENT_LISTS
        WHERE  LIST_ID = @LIST_ID
      ) AS a
WHERE NOT EXISTS  
      ( SELECT *
        FROM   DBO.PATIENT_LIST_BESPOKE AS b
        WHERE  a.LIST_ID = b.LIST_ID         -- but not for this
      ) ;

আমি মনে করি এটি এখন বেশ স্পষ্ট যে 2nq ক্যোয়ারির ২ য় অংশের জন্য, ফিল্টারড সূচকটি ব্যবহার করা যাবে না।


বিস্তারিতভাবে, এই প্রশ্নগুলির বিষয়ে, LIST_IDপ্রথম সারণীতে 4 ধরণের মান রয়েছে:

  • (ক) মানগুলি যেগুলির সাথে দ্বিতীয় সারণীতে মিল রয়েছে সারিগুলি END_DTTM IS NULL

  • (খ) যে মানগুলি দ্বিতীয় সারণীতে মেলানো সারি রয়েছে তার সাথে END_DTTM IS NULLএবং সাথে উভয়ই END_DTTM IS NOT NULL

  • (গ) মানগুলি যেগুলির সাথে দ্বিতীয় সারণীতে মিল রয়েছে সারিগুলি END_DTTM IS NOT NULL

  • (d) দ্বিতীয় টেবিলে মানগুলির কোনও মিল নেই।

এখন, 1 ম কোয়েরি সমস্ত ধরণের (ক) এবং (খ) সম্ভবত বহুবার (দ্বিতীয় টেবিলের সাথে তাদের মিলের সারি রয়েছে END_DTTM IS NULL) এবং সমস্ত সারি (গ) এবং (ডি) ঠিক একবারে ফিরে আসবে ( এটি বাইরের যোগদানের অ-মিল অংশ)।

২ য় ক্যোয়ারী সমস্ত ধরণের (ক) এবং (খ) সম্ভবত বহুবার (দ্বিতীয় টেবিলের সাথে তাদের মিলের সারি রয়েছে END_DTTM IS NULL) এবং টাইপের সমস্ত সারি (ডি) ঠিক একবারে ফিরে আসবে ।
এটি (গ) প্রকারের কোনও মান ফেরত দেবে না কারণ যোগদানটি দ্বিতীয় সারণীতে মিলবে সারিগুলি খুঁজে পাবে (তবে এটিতে থাকবে END_DTTM IS NOT NULL) এবং সেগুলি পরবর্তী WHEREধারা দ্বারা মুছে ফেলা হবে ।

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