কী লুকআপ (ক্লাস্টারড) অপারেটর বাদ দিন যা কার্য সম্পাদনকে ধীর করে দেয়


16

আমি আমার সম্পাদন পরিকল্পনার কী কী চেহারা (ক্লাস্টারড) অপারেটরকে বাদ দিতে পারি?

সারণীতে tblQuotesইতিমধ্যে একটি ক্লাস্টারড ইনডেক্স (অন QuoteID) এবং ২ non টি নন-ক্ল্লাস্টার্ড সূচক রয়েছে, তাই আমি আর কোনও তৈরি না করার চেষ্টা করছি।

আমি QuoteIDআমার ক্যোয়ারিতে ক্লাস্টারড ইনডেক্স কলামটি রেখেছি, আশা করি এটি সহায়তা করবে - তবে দুর্ভাগ্যক্রমে এখনও একই আছে।

এখানে কার্যকর করার পরিকল্পনা

অথবা এটি দেখুন:

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

এই কী লুকআপ অপারেটর বলেছেন:

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

প্রশ্ন:

declare
        @EffDateFrom datetime ='2017-02-01',
        @EffDateTo   datetime ='2017-08-28'

SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

IF OBJECT_ID('tempdb..#Data') IS NOT NULL
    DROP TABLE #Data 
CREATE TABLE #Data
(
    QuoteID int NOT NULL,   --clustered index

    [EffectiveDate] [datetime] NULL, --not indexed
    [Submitted] [int] NULL,
    [Quoted] [int] NULL,
    [Bound] [int] NULL,
    [Exonerated] [int] NULL,
    [ProducerLocationId] [int] NULL,
    [ProducerName] [varchar](300) NULL,
    [BusinessType] [varchar](50) NULL,
    [DisplayStatus] [varchar](50) NULL,
    [Agent] [varchar] (50) NULL,
    [ProducerContactGuid] uniqueidentifier NULL
)
INSERT INTO #Data
    SELECT 
        tblQuotes.QuoteID,

          tblQuotes.EffectiveDate,
          CASE WHEN lstQuoteStatus.QuoteStatusID >= 1   THEN 1 ELSE 0 END AS Submitted,
          CASE WHEN lstQuoteStatus.QuoteStatusID = 2 or lstQuoteStatus.QuoteStatusID = 3 or lstQuoteStatus.QuoteStatusID = 202 THEN 1 ELSE 0 END AS Quoted,
          CASE WHEN lstQuoteStatus.Bound = 1 THEN 1 ELSE 0 END AS Bound,
          CASE WHEN lstQuoteStatus.QuoteStatusID = 3 THEN 1 ELSE 0 END AS Exonareted,
          tblQuotes.ProducerLocationID,
          P.Name + ' / '+ P.City as [ProducerName], 
        CASE WHEN tblQuotes.PolicyTypeID = 1 THEN 'New Business' 
             WHEN tblQuotes.PolicyTypeID = 3 THEN 'Rewrite'
             END AS BusinessType,
        tblQuotes.DisplayStatus,
        tblProducerContacts.FName +' '+ tblProducerContacts.LName as Agent,
        tblProducerContacts.ProducerContactGUID
FROM    tblQuotes 
            INNER JOIN lstQuoteStatus 
                on tblQuotes.QuoteStatusID=lstQuoteStatus.QuoteStatusID
            INNER JOIN tblProducerLocations P 
                On P.ProducerLocationID=tblQuotes.ProducerLocationID
            INNER JOIN tblProducerContacts 
                ON dbo.tblQuotes.ProducerContactGuid = tblProducerContacts.ProducerContactGUID

WHERE   DATEDIFF(D,@EffDateFrom,tblQuotes.EffectiveDate)>=0 AND DATEDIFF(D, @EffDateTo, tblQuotes.EffectiveDate) <=0
        AND dbo.tblQuotes.LineGUID = '6E00868B-FFC3-4CA0-876F-CC258F1ED22D'--Surety
        AND tblQuotes.OriginalQuoteGUID is null

select * from #Data

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

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


আনুমানিক বনাম আসল সারিগুলি একটি উল্লেখযোগ্য পার্থক্য দেখায়। সম্ভবত এসকিউএল একটি খারাপ পরিকল্পনা বাছাই করছে কারণ এটিতে ভাল অনুমান করার মতো ডেটা নেই। আপনি কতবার আপনার পরিসংখ্যান আপডেট করেন?
আরডিফোজ

উত্তর:


23

বিভিন্ন স্বাদের মূল অনুসন্ধানগুলি ঘটে যখন ক্যোয়ারী প্রসেসরের ফলাফলগুলি প্রত্যাবর্তনের জন্য ক্যোয়ারির জন্য প্রয়োজনীয় সারিগুলি সনাক্ত করতে ব্যবহৃত সূচীতে সঞ্চিত নয় এমন কলামগুলি থেকে মানগুলি পাওয়া দরকার।

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

USE tempdb;

IF OBJECT_ID(N'dbo.Table1', N'U') IS NOT NULL
DROP TABLE dbo.Table1
GO

CREATE TABLE dbo.Table1
(
    Table1ID int NOT NULL IDENTITY(1,1)
    , Table1Data nvarchar(30) NOT NULL
);

CREATE INDEX IX_Table1
ON dbo.Table1 (Table1ID);
GO

আমরা টেবিলের মধ্যে ১,০০,০০০ সারি সন্নিবেশ করব যাতে আমাদের সাথে কাজ করার জন্য কিছু ডেটা থাকে:

INSERT INTO dbo.Table1 (Table1Data)
SELECT TOP(1000000) LEFT(c.name, 30)
FROM sys.columns c
    CROSS JOIN sys.columns c1
    CROSS JOIN sys.columns c2;
GO

এখন, আমরা "প্রকৃত" বাস্তবায়ন পরিকল্পনাটি প্রদর্শনের বিকল্পের সাহায্যে ডেটাটি জিজ্ঞাসা করব:

SELECT *
FROM dbo.Table1
WHERE Table1ID = 500000;

ক্যোয়ারী পরিকল্পনাটি দেখায়:

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

ক্যোরিটি IX_Table1সারিটি সন্ধান করতে সূচকে দেখায় Table1ID = 5000000যেহেতু সেই সূচকটি দেখলে সেই মানটির সন্ধানের পুরো টেবিলটি স্ক্যান করার চেয়ে অনেক দ্রুত। যাইহোক, ক্যোয়ারির ফলাফলগুলি সন্তুষ্ট করতে, ক্যোয়ারী প্রসেসরটিকে অবশ্যই সারণীর অন্যান্য কলামগুলির জন্য মানটি খুঁজে পেতে হবে; এখানেই "আরআইডি লুকআপ" আসে It Table1IDএটি Table1Dataকলাম থেকে মানগুলি প্রাপ্ত করে 500000 এর মান যুক্ত সারির আইডি (আরআইডি লুকআপে আরআইডি) সারণীতে দেখায় । আপনি যদি পরিকল্পনার "আরআইডি লুকআপ" নোডের উপরে মাউসটি ঘোরােন তবে আপনি এটি দেখতে পাবেন:

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

"আউটপুট তালিকা "টিতে আরআইডি লুকআপ দ্বারা ফিরে আসা কলামগুলি থাকে।

একটি ক্লাস্টার ইনডেক্স এবং একটি ক্লাস্টারযুক্ত সূচক সহ একটি টেবিল একটি আকর্ষণীয় উদাহরণ তৈরি করে। নীচের টেবিলটিতে তিনটি কলাম রয়েছে; আইডি যা ক্লাস্টারিং কী, Datযা একটি নন-ক্লাস্টারযুক্ত সূচক IX_Tableএবং তৃতীয় কলামে সূচিত হয় Oth

USE tempdb;

IF OBJECT_ID(N'dbo.Table1', N'U') IS NOT NULL
DROP TABLE dbo.Table1
GO

CREATE TABLE dbo.Table1
(
    ID int NOT NULL IDENTITY(1,1) 
        PRIMARY KEY CLUSTERED
    , Dat nvarchar(30) NOT NULL
    , Oth nvarchar(3) NOT NULL
);

CREATE INDEX IX_Table1
ON dbo.Table1 (Dat);
GO

INSERT INTO dbo.Table1 (Dat, Oth)
SELECT TOP(1000000) CRYPT_GEN_RANDOM(30), CRYPT_GEN_RANDOM(3)
FROM sys.columns c
    CROSS JOIN sys.columns c1
    CROSS JOIN sys.columns c2;
GO

এই উদাহরণ কোয়েরি নিন:

SELECT *
FROM dbo.Table1
WHERE Dat = 'Test';

আমরা এসকিউএল সার্ভারকে টেবিল থেকে প্রতিটি কলামটি ফিরে আসতে বলছি যেখানে Datকলামটিতে শব্দ রয়েছে Test। আমাদের এখানে কয়েকটি পছন্দ আছে; আমরা টেবিল (অর্থাত ক্লাস্টার INDEX) তাকান করতে পারেন - কিন্তু যে সমগ্র জিনিস স্ক্যান যেহেতু সারণী নির্দেশ দেওয়া হয় ফলস্বরূপ ঘটা হবে IDকলাম, যা আমাদের কিছুই যা সম্পর্কে সারি (গুলি) থাকতে বলে TestDatকলাম। অন্য বিকল্পটি (এবং এসকিউএল সার্ভার দ্বারা নির্বাচিত একটি) IX_Table1সারিটি সন্ধানের জন্য নন-ক্লাস্টারড ইনডেক্সের সন্ধানের সমন্বয়ে গঠিত হয়েছে Dat = 'Test', যদিও আমাদের Othপাশাপাশি কলামটিও প্রয়োজন তাই এসকিউএল সার্ভারকে অবশ্যই "কী ব্যবহার করে ক্লাস্টারড সূচীতে একটি অনুসন্ধান করতে হবে must চেহারা "অপারেশন। এটি তার জন্য এই পরিকল্পনা:

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

আমরা তাই অ ক্লাস্টার সূচক সংশোধন এটি যদি অন্তর্ভুক্তOth কলাম:

DROP INDEX IX_Table1
ON dbo.Table1;
GO

CREATE INDEX IX_Table1
ON dbo.Table1 (Dat)
INCLUDE (Oth);        <---- This is the only change
GO

তারপরে কোয়েরিটি আবার চালান:

SELECT *
FROM dbo.Table1
WHERE Dat = 'Test';

আমরা এখন একটি একক অ ক্লাস্টার সূচক চাইতে যেহেতু SQL সার্ভার কেবল যেখানে সারি খোজা দরকার দেখতে Dat = 'Test'মধ্যে IX_Table1সূচক, যার জন্য মান অন্তর্ভুক্ত Othএবং জন্য মান, IDকলাম (প্রাথমিক কী), যা যে অ স্বয়ংক্রিয়ভাবে উপস্থিত গুচ্ছ সূচক পরিকল্পনা:

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


6

কী অনুসন্ধানের কারণ হ'ল ইঞ্জিন এমন একটি সূচি ব্যবহার করতে বেছে নিয়েছে যাতে আপনি আনার চেষ্টা করছেন এমন সমস্ত কলাম নেই। সুতরাং সূচকটি নির্বাচন করুন এবং যেখানে বিবৃতিতে কলামগুলি কভার করছে না।

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

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


আরও মনে রাখবেন যে অনেকগুলি সূচী সম্পাদন পরিকল্পনার সংকলনকে বিভ্রান্ত করতে পারে এবং এর ফলে উপ-অনুকূল নির্বাচনের ফলাফলও হতে পারে।
ল্যাপসাইড

4

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

এই ক্যোয়ারির উদ্দেশ্যগুলির জন্য, tblQuotes27 টি নন-ক্লাস্টার্ড ইনডেক্সের প্রয়োজন নেই। এটির জন্য ১ টি ক্লাস্টারড ইনডেক্স এবং ৫ টি নন-ক্লাস্টারড ইনডেক্স বা সম্ভবত non টি ক্লাস্টারযুক্ত সূচক প্রয়োজন।

এই ক্যোয়ারীটি এই কলামগুলিতে সূচি চাইবে:

QuoteStatusID
ProducerLocationID
ProducerContactGuid
EffectiveDate
LineGUID
OriginalQuoteGUID

আমি নিম্নলিখিত কোডটিও লক্ষ্য করেছি:

DATEDIFF(D, @EffDateFrom, tblQuotes.EffectiveDate) >= 0 AND 
DATEDIFF(D, @EffDateTo, tblQuotes.EffectiveDate) <= 0

হয় NON Sargableঅর্থাত এটা ইনডেক্স ব্যবহার করতে পারবে না।

কোডটি SARgableএটিকে এটিতে পরিবর্তন করতে:

tblQuotes.EffectiveDate >= @EffDateFrom 
AND  tblQuotes.EffectiveDate <= @EffDateFrom

আপনার মূল প্রশ্নের উত্তর দিতে, "আপনি কী কীভাবে সন্ধান করছেন":

আপনি পেয়ে যাচ্ছেন KEY Look upকারণ ক্যোয়ারীতে বর্ণিত কিছু কলাম কোনও আচ্ছাদন সূচীতে উপস্থিত নেই।

আপনি Google এবং প্রায় অধ্যয়ন করতে পারেন Covering Indexবা Include index

আমার উদাহরণ হিসাবে ধরুন tblQuotes.QuoteStatusID নন ক্লাস্টারড ইনডেক্স তবে আমি ডিসপ্লেস্ট্যাটাসটিও কভার করতে পারি। যেহেতু আপনি রেজাল্টে ডিসপ্লেস্ট্যাটাস চান। যে কোনও কলাম যা সূচকে উপস্থিত নেই এবং ফলাফলসেটে উপস্থিত রয়েছে তা এড়ানোর জন্য আচ্ছাদন করা যেতে পারে KEY Look Up or Bookmark lookup। এটি সূচকটি কভার করার একটি উদাহরণ:

create nonclustered index tblQuotes_QuoteStatusID 
on tblQuotes(QuoteStatusID)
include(DisplayStatus);

** অস্বীকৃতি: ** উপরে মনে রাখবেন কেবলমাত্র আমার উদাহরণ ডিসপ্লেস্ট্যাটাস বিশ্লেষণের পরে অন্যান্য নন সিআই দিয়ে আচ্ছাদিত হতে পারে।

একইভাবে আপনার প্রশ্নের সাথে জড়িত অন্যান্য টেবিলগুলিতে সূচি এবং প্রচ্ছদ সূচক তৈরি করতে হবে।

আপনি Index SCANআপনার পরিকল্পনায়ও পাচ্ছেন ।

এটি ঘটতে পারে কারণ টেবিলে কোনও সূচক নেই বা যখন প্রচুর পরিমাণে ডেটা থাকে তখন অপ্টিমাইজার সূচক অনুসন্ধানের পরিবর্তে স্ক্যান করার সিদ্ধান্ত নিতে পারে।

এটি কারণেও ঘটতে পারে High cardinality। ত্রুটিযুক্ত যোগদানের কারণে প্রয়োজনের চেয়ে বেশি সংখ্যক সারি পাওয়া। এটিও সংশোধন করা যায়।

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