এই শিকারীটির চেয়ে অনুসন্ধানের চেয়ে দ্রুত স্ক্যান কেন হয়?


30

আমি একটি ক্যোয়ারি পারফরম্যান্স ইস্যুটি পুনরুত্পাদন করতে সক্ষম হয়েছি যা আমি অপ্রত্যাশিত হিসাবে বর্ণনা করব। আমি একটি উত্তর খুঁজছি যা ইন্টার্নালগুলিতে নিবদ্ধ

আমার মেশিনে, নিম্নলিখিত কোয়েরিটি একটি ক্লাস্টারড ইনডেক্স স্ক্যান করে এবং সিপিইউ সময় সম্পর্কে প্রায় 6.8 সেকেন্ড সময় নেয়:

SELECT ID1, ID2
FROM two_col_key_test WITH (FORCESCAN)
WHERE ID1 NOT IN
(
N'1', N'2',N'3', N'4', N'5',
N'6', N'7', N'8', N'9', N'10',
N'11', N'12',N'13', N'14', N'15',
N'16', N'17', N'18', N'19', N'20'
)
AND (ID1 = N'FILLER TEXT' AND ID2 >= N'' OR (ID1 > N'FILLER TEXT'))
ORDER BY ID1, ID2 OFFSET 12000000 ROWS FETCH FIRST 1 ROW ONLY
OPTION (MAXDOP 1);

নিম্নলিখিত কোয়েরিটি একটি ক্লাস্টারযুক্ত সূচীটি অনুসন্ধান করে (কেবলমাত্র পার্থক্যটি FORCESCANইঙ্গিতটি সরিয়ে দিচ্ছে ) তবে সিপিইউ সময় সম্পর্কে প্রায় 18.2 সেকেন্ড সময় নেয়:

SELECT ID1, ID2
FROM two_col_key_test
WHERE ID1 NOT IN
(
N'1', N'2',N'3', N'4', N'5',
N'6', N'7', N'8', N'9', N'10',
N'11', N'12',N'13', N'14', N'15',
N'16', N'17', N'18', N'19', N'20'
)
AND (ID1 = N'FILLER TEXT' AND ID2 >= N'' OR (ID1 > N'FILLER TEXT'))
ORDER BY ID1, ID2 OFFSET 12000000 ROWS FETCH FIRST 1 ROW ONLY
OPTION (MAXDOP 1);

ক্যোয়ারী পরিকল্পনাগুলি বেশ অনুরূপ। উভয় প্রশ্নের জন্য ক্লাস্টার্ড সূচক থেকে 120000001 টি সারি পাঠ করা হয়েছে:

ক্যোয়ারী পরিকল্পনা

আমি এসকিউএল সার্ভার 2017 সিইউ 10 এ আছি two_col_key_testটেবিলটি তৈরি এবং পপুলেট করার জন্য এখানে কোড দেওয়া আছে :

drop table if exists dbo.two_col_key_test;

CREATE TABLE dbo.two_col_key_test (
    ID1 NVARCHAR(50) NOT NULL,
    ID2 NVARCHAR(50) NOT NULL,
    FILLER NVARCHAR(50),
    PRIMARY KEY (ID1, ID2)
);

DROP TABLE IF EXISTS #t;

SELECT TOP (4000) 0 ID INTO #t
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
OPTION (MAXDOP 1);


INSERT INTO dbo.two_col_key_test WITH (TABLOCK)
SELECT N'FILLER TEXT' + CASE WHEN ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) > 8000000 THEN N' 2' ELSE N'' END
, ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
, NULL
FROM #t t1
CROSS JOIN #t t2;

আমি এমন একটি উত্তরের জন্য প্রত্যাশা করছি যা কল স্ট্যাকের রিপোর্টিংয়ের চেয়ে বেশি কিছু করে। উদাহরণস্বরূপ, আমি দেখতে পাচ্ছি যে sqlmin!TCValSSInRowExprFilter<231,0,0>::GetDataXদ্রুতটির তুলনায় ধীর ক্যোয়ারিতে উল্লেখযোগ্যভাবে আরও সিপিইউ চক্র লাগে:

perview

সেখানে থামার পরিবর্তে, আমি বুঝতে চাই যে এটি কী এবং কেন দুটি প্রশ্নের মধ্যে এত বড় পার্থক্য রয়েছে।

এই দুটি প্রশ্নের জন্য কেন সিপিইউ সময়ের মধ্যে একটি বড় পার্থক্য রয়েছে?

উত্তর:


31

এই দুটি প্রশ্নের জন্য কেন সিপিইউ সময়ের মধ্যে একটি বড় পার্থক্য রয়েছে?

স্ক্যান পরিকল্পনাটি প্রতিটি সারিটির জন্য নিম্নলিখিত ধাক্কাযুক্ত অ-সরগেবল (অবশিষ্ট) প্রিকেটকে মূল্যায়ন করে:

[two_col_key_test].[ID1]<>N'1' 
AND [two_col_key_test].[ID1]<>N'10' 
AND [two_col_key_test].[ID1]<>N'11' 
AND [two_col_key_test].[ID1]<>N'12' 
AND [two_col_key_test].[ID1]<>N'13' 
AND [two_col_key_test].[ID1]<>N'14' 
AND [two_col_key_test].[ID1]<>N'15' 
AND [two_col_key_test].[ID1]<>N'16' 
AND [two_col_key_test].[ID1]<>N'17' 
AND [two_col_key_test].[ID1]<>N'18' 
AND [two_col_key_test].[ID1]<>N'19' 
AND [two_col_key_test].[ID1]<>N'2' 
AND [two_col_key_test].[ID1]<>N'20' 
AND [two_col_key_test].[ID1]<>N'3' 
AND [two_col_key_test].[ID1]<>N'4' 
AND [two_col_key_test].[ID1]<>N'5' 
AND [two_col_key_test].[ID1]<>N'6' 
AND [two_col_key_test].[ID1]<>N'7' 
AND [two_col_key_test].[ID1]<>N'8' 
AND [two_col_key_test].[ID1]<>N'9' 
AND 
(
    [two_col_key_test].[ID1]=N'FILLER TEXT' 
    AND [two_col_key_test].[ID2]>=N'' 
    OR [two_col_key_test].[ID1]>N'FILLER TEXT'
)

অবশিষ্ট স্ক্যান

সিক প্ল্যান দুটি সন্ধানকারী অপারেশন করে:

Seek Keys[1]: 
    Prefix: 
    [two_col_key_test].ID1 = Scalar Operator(N'FILLER TEXT'), 
        Start: [two_col_key_test].ID2 >= Scalar Operator(N'')
Seek Keys[1]: 
    Start: [two_col_key_test].ID1 > Scalar Operator(N'FILLER TEXT')

... প্রিডিকেটের এই অংশটি মেলে:

(ID1 = N'FILLER TEXT' AND ID2 >= N'' OR (ID1 > N'FILLER TEXT'))

উপরের সন্ধান শর্তগুলি (আপনার উদাহরণের সমস্ত সারি) পাস করে এমন সারিগুলিতে একটি অবশিষ্টাংশের প্রাকটিক প্রয়োগ করা হয়।

তবে, প্রতিটি বৈষম্য জন্য দুটি পৃথক পরীক্ষার দ্বারা প্রতিস্থাপিত হয় কম OR তার চেয়ে অনেক বেশী :

([two_col_key_test].[ID1]<N'1' OR [two_col_key_test].[ID1]>N'1') 
AND ([two_col_key_test].[ID1]<N'10' OR [two_col_key_test].[ID1]>N'10') 
AND ([two_col_key_test].[ID1]<N'11' OR [two_col_key_test].[ID1]>N'11') 
AND ([two_col_key_test].[ID1]<N'12' OR [two_col_key_test].[ID1]>N'12') 
AND ([two_col_key_test].[ID1]<N'13' OR [two_col_key_test].[ID1]>N'13') 
AND ([two_col_key_test].[ID1]<N'14' OR [two_col_key_test].[ID1]>N'14') 
AND ([two_col_key_test].[ID1]<N'15' OR [two_col_key_test].[ID1]>N'15') 
AND ([two_col_key_test].[ID1]<N'16' OR [two_col_key_test].[ID1]>N'16') 
AND ([two_col_key_test].[ID1]<N'17' OR [two_col_key_test].[ID1]>N'17') 
AND ([two_col_key_test].[ID1]<N'18' OR [two_col_key_test].[ID1]>N'18') 
AND ([two_col_key_test].[ID1]<N'19' OR [two_col_key_test].[ID1]>N'19') 
AND ([two_col_key_test].[ID1]<N'2' OR [two_col_key_test].[ID1]>N'2') 
AND ([two_col_key_test].[ID1]<N'20' OR [two_col_key_test].[ID1]>N'20') 
AND ([two_col_key_test].[ID1]<N'3' OR [two_col_key_test].[ID1]>N'3') 
AND ([two_col_key_test].[ID1]<N'4' OR [two_col_key_test].[ID1]>N'4') 
AND ([two_col_key_test].[ID1]<N'5' OR [two_col_key_test].[ID1]>N'5') 
AND ([two_col_key_test].[ID1]<N'6' OR [two_col_key_test].[ID1]>N'6') 
AND ([two_col_key_test].[ID1]<N'7' OR [two_col_key_test].[ID1]>N'7') 
AND ([two_col_key_test].[ID1]<N'8' OR [two_col_key_test].[ID1]>N'8') 
AND ([two_col_key_test].[ID1]<N'9' OR [two_col_key_test].[ID1]>N'9')

অবশিষ্ট অবলম্বন

প্রতিটি অসমতার পুনর্লিখন যেমন:

[ID1] <> N'1'  ->  [ID1]<N'1' OR [ID1]>N'1'

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

আপনি অ-সরগেবল পূর্বাভাসের চাপকে অক্ষমযুক্ত ট্রেস পতাকা 9130 দিয়ে অক্ষম করে এটি আরও স্পষ্ট দেখতে পাচ্ছেন That

স্ক্যান

চাইতে

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

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

এটিও লক্ষ করুন যে মূল ("লিগ্যাসি") কার্ডিনালিটি অনুমানের মডেলটি এই কোয়েরির জন্য ডিফল্টরূপে একটি স্ক্যান নির্বাচন করতে ঘটে।

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