সূচী দ্রুত কার্যকর করা হচ্ছে না এবং কিছু ক্ষেত্রে কোয়েরিটি ধীর করছে। এটা এমন কেন?


34

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

পরীক্ষার সারণী তৈরি করতে এবং এটি ডেটা দিয়ে পূরণ করার ক্যোয়ারীটি হ'ল:

CREATE TABLE [dbo].[IndexTestTable](
    [id] [int] IDENTITY(1,1) PRIMARY KEY,
    [Name] [nvarchar](20) NULL,
    [val1] [bigint] NULL,
    [val2] [bigint] NULL)

DECLARE @counter INT;
SET @counter = 1;

WHILE @counter < 500000
BEGIN
    INSERT INTO IndexTestTable
      (
        -- id -- this column value is auto-generated
        NAME,
        val1,
        val2
      )
    VALUES
      (
        'Name' + CAST((@counter % 100) AS NVARCHAR),
        RAND() * 10000,
        RAND() * 20000
      );

    SET @counter = @counter + 1;
END

-- Index in question
CREATE NONCLUSTERED INDEX [IndexA] ON [dbo].[IndexTestTable]
(
    [Name] ASC
)
INCLUDE (   [id],
    [val1],
    [val2])

এখন ক্যোয়ারী 1, যা উন্নত হয়েছে (কেবলমাত্র সামান্য তবে উন্নতি ধারাবাহিক):

SELECT *
FROM   IndexTestTable I1
       JOIN IndexTestTable I2
            ON  I1.ID = I2.ID
WHERE  I1.Name = 'Name1'

সূচি ছাড়াই পরিসংখ্যান এবং সম্পাদন পরিকল্পনা (এই ক্ষেত্রে সারণীটি ডিফল্ট ক্লাস্টারড সূচক ব্যবহার করে):

(5000 row(s) affected)
Table 'IndexTestTable'. Scan count 2, logical reads 5580, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 109 ms,  elapsed time = 294 ms.

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

এখন সূচক সক্ষম হয়েছে:

(5000 row(s) affected)
Table 'IndexTestTable'. Scan count 2, logical reads 2819, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 94 ms,  elapsed time = 231 ms.

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

সূচকের কারণে এখন যে ক্যোয়ারী ধীর হয়ে যায় (ক্যোরিটি অর্থহীন তাই এটি কেবল পরীক্ষার জন্য তৈরি হয়েছে):

SELECT I1.Name,
       SUM(I1.val1),
       SUM(I1.val2),
       MIN(I2.Name),
       SUM(I2.val1),
       SUM(I2.val2)
FROM   IndexTestTable I1
       JOIN IndexTestTable I2
            ON  I1.Name = I2.Name
WHERE   
       I2.Name = 'Name1'
GROUP BY
       I1.Name

ক্লাস্টারড ইনডেক্স সক্ষম করা সহ:

(1 row(s) affected)
Table 'IndexTestTable'. Scan count 4, logical reads 60, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 155106, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 17207 ms,  elapsed time = 17337 ms.

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

এখন সূচক অক্ষম সহ:

(1 row(s) affected)
Table 'IndexTestTable'. Scan count 5, logical reads 8642, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 2, logical reads 165212, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 17691 ms,  elapsed time = 9073 ms.

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

প্রশ্নগুলি হ'ল:

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

এসকিউএল সার্ভার 2012 ব্যবহার করা

উত্তর:


23

যদিও সূচকটি এসকিউএল সার্ভারের দ্বারা প্রস্তাবিত, তবুও কেন এটি উল্লেখযোগ্য পার্থক্যের দ্বারা জিনিসগুলিকে মন্থর করে?

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

অনুপস্থিত সূচী পরামর্শগুলি সম্পর্কে অন্য কথাটি হ'ল তারা হ'ল অপটিমাইজারের ব্যয়বহুল মডেলের উপর ভিত্তি করে এবং প্রস্তাবিত সূচকটি ক্যোয়ারের আনুমানিক ব্যয়কে কতটা হ্রাস করতে পারে তার মাধ্যমে অপ্টিমাইজারটি অনুমান করে । এখানে মূল শব্দগুলি হ'ল "মডেল" এবং "অনুমান"। ক্যোয়ারী অপ্টিমাইজার আপনার হার্ডওয়্যার কনফিগারেশন বা অন্যান্য সিস্টেম কনফিগারেশন বিকল্পগুলি সম্পর্কে খুব কম জানেন - এর মডেলটি বেশিরভাগ সময় বেশিরভাগ সিস্টেমে বেশিরভাগ লোকের পক্ষে যুক্তিসঙ্গত পরিকল্পনা ফলাফল তৈরির জন্য নির্দিষ্ট সংখ্যার উপর ভিত্তি করে তৈরি হয়। ব্যবহৃত সঠিক ব্যয়ের সংখ্যা সহ সমস্যাগুলি বাদ দিয়ে ফলাফলগুলি সর্বদা অনুমান করা হয় - এবং অনুমানগুলি ভুল হতে পারে।

নেস্টেড লুপ যোগ দিন যা বেশিরভাগ সময় নিচ্ছে এবং কীভাবে এটি কার্যকর করার সময়টিকে আরও উন্নত করতে পারে?

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

এমন কিছু আছে যা আমি ভুল করছি বা মিস করেছি?

আপনি যে প্রধান জিনিসটি মিস করছেন তা হ'ল অপ্লিটর্টার্ড সূচকটি ব্যবহার করার পরিকল্পনার অপ্টিমাইজারের মডেল অনুসারে কম অনুমান ব্যয় হলেও এটির কার্যকর কার্যকর সময় সমস্যা রয়েছে। আপনি যদি ক্লাস্টারড ইনডেক্স ব্যবহার করে পরিকল্পনায় থ্রেডগুলি জুড়ে সারিগুলির বিতরণটি দেখেন তবে আপনি সম্ভবত যুক্তিসঙ্গতভাবে ভাল বিতরণ দেখতে পাবেন:

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

ননক্র্লাস্টারড ইনডেক্স সিক ব্যবহার করে পরিকল্পনায় কাজটি একটি থ্রেড দ্বারা সম্পূর্ণভাবে সম্পাদিত হবে:

পরিকল্পনা সন্ধান করুন

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

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

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

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

উদাহরণটি সম্পূর্ণ করার জন্য এবং আমি উল্লেখ করেছি যে কয়েকটি বিষয় বর্ণনা করার জন্য, আরও ভাল কাজের বিতরণ পাওয়ার একটি উপায় হল সমান্তরাল সম্পাদন চালানোর জন্য অস্থায়ী টেবিল ব্যবহার করা:

SELECT
    val1,
    val2
INTO #Temp
FROM dbo.IndexTestTable AS ITT
WHERE Name = N'Name1';

SELECT 
    N'Name1',
    SUM(T.val1),
    SUM(T.val2),
    MIN(I2.Name),
    SUM(I2.val1),
    SUM(I2.val2)
FROM   #Temp AS T
CROSS JOIN IndexTestTable I2
WHERE
    I2.Name = 'Name1'
OPTION (FORCE ORDER, QUERYTRACEON 8690);

DROP TABLE #Temp;

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

অনুকূল পরিকল্পনা

আমার সিস্টেমে, এই পরিকল্পনাটি ক্লাস্টারড ইনডেক্স স্ক্যান সংস্করণের চেয়ে উল্লেখযোগ্যভাবে দ্রুত সম্পাদন করে।

আপনি যদি সমান্তরাল ক্যোয়ারী এক্সিকিউশনের ইন্টার্নালগুলি সম্পর্কে আরও জানতে আগ্রহী হন তবে আপনি আমার পাস সামিট ২০১৩ সেশনের রেকর্ডিং দেখতে পছন্দ করতে পারেন ।


0

এটি আসলে সূচকের প্রশ্ন নয়, এটি আরও খারাপভাবে লেখা প্রশ্ন। আপনার নামের একমাত্র 100 টি অনন্য মান রয়েছে, এটি প্রতিটি নাম 5000 এর অনন্য গণনা ছেড়ে দেয়।

সুতরাং টেবিল 1 এর প্রতিটি লাইনের জন্য আপনি টেবিল 2 থেকে 5000 এ যোগদান করছেন। 25020004 লাইন বলতে পারেন?

এটি চেষ্টা করুন, নোট করুন এটি কেবলমাত্র 1 সূচকের সাথে, আপনি তালিকাবদ্ধ করেছেন।

    DECLARE @Distincts INT
    SET @Distincts = (SELECT  TOP 1 COUNT(*) FROM IndexTestTable I1 WHERE I1.Name = 'Name1' GROUP BY I1.Name)
    SELECT I1.Name
    , @Distincts
    , SUM(I1.val1) * @Distincts
    , SUM(I1.val2) * @Distincts
    , MIN(I2.Name)
    , SUM(I2.val1)
    , SUM(I2.val2)
    FROM   IndexTestTable I1
    LEFT OUTER JOIN

    (
        SELECT I2.Name
        , SUM(I2.val1) val1
        , SUM(I2.val2) val2
        FROM IndexTestTable I2
        GROUP BY I2.Name
    ) I2 ON  I1.Name = I2.Name
    WHERE I1.Name = 'Name1'
    GROUP BY  I1.Name

এবং সময়:

    SQL Server parse and compile time: 
       CPU time = 0 ms, elapsed time = 8 ms.
    Table 'IndexTestTable'. Scan count 1, logical reads 31, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

     SQL Server Execution Times:
       CPU time = 0 ms,  elapsed time = 1 ms.

    (1 row(s) affected)
    Table 'IndexTestTable'. Scan count 2, logical reads 62, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
    Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

     SQL Server Execution Times:
       CPU time = 16 ms,  elapsed time = 10 ms.

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

খারাপভাবে গঠিত প্রশ্নের জন্য আপনি এসকিউএল সূচকগুলিকে দোষ দিতে পারবেন না


1
উত্তরের জন্য ধন্যবাদ, এবং হ্যাঁ ক্যোয়ারীটি উন্নত করা যেতে পারে, তবে আমার প্রশ্নের যুক্তিটি হ'ল ডিফল্ট সূচক (কেবলমাত্র প্রাথমিক কীতে) কেন এটি কম সময় নেয় এবং ক্লাস্টারযুক্ত নীতিমালা উপস্থিত না করে প্রতিটি সারির জন্য? যোগদানের টেবিল, যুক্ত টেবিল সারিটি দ্রুত খুঁজে পাওয়া উচিত, যা ক্যোয়ারী এক্সিকিউশন পরিকল্পনায় প্রতিফলিত হয় এবং সূচি সন্ধানের ক্ষেত্রে ইনডেক্স সিকি ব্যয় কম হয়, তবে কেন এখনও ধীর হয়? এছাড়াও নেস্টেড লুপের বাম বাহিরের জোনে কী রয়েছে যা মন্দা সৃষ্টি করছে? এই মন্তব্যটি যুক্ত করার জন্য, প্রশ্নটি আরও স্পষ্ট করার জন্য আমি প্রশ্নটি সম্পাদনা করেছি।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.