হিস্টগ্রামের বাইরে কার্ডিনালিটির অনুমান


14

সেটআপ

একটি কার্ডিনালিটি অনুমান বুঝতে আমার কিছুটা সমস্যা হচ্ছে। এখানে আমার পরীক্ষার সেটআপ:

  • স্ট্যাক ওভারফ্লো ডাটাবেসের 2010 সংস্করণ
  • এসকিউএল সার্ভার 2017 সিইউ 15 + জিডিআর (KB4505225) - 14.0.3192.2
  • নতুন সিই (সামঞ্জস্যের স্তর 140)

আমার এই প্রকল্প আছে:

USE StackOverflow2010;
GO

CREATE OR ALTER PROCEDURE #sp_PostsByCommentCount
    @CommentCount int
AS
BEGIN
    SELECT * 
    FROM dbo.Posts p
    WHERE 
        p.CommentCount = @CommentCount
    OPTION (RECOMPILE); 
END;
GO

dbo.Postsটেবিলে কোনও অবিবাহিত সূচী বা পরিসংখ্যান নেই (একটি ক্লাস্টার ইনডেক্স চালু আছে Id)।

dbo.Postsএটির জন্য আনুমানিক পরিকল্পনা জিজ্ঞাসা করার সময়, "আনুমানিক সারিগুলি" বেরিয়ে আসে 1,934.99:

EXEC #sp_PostsByCommentCount @CommentCount = 51;

নিম্নলিখিত পরিসংখ্যান অবজেক্টটি স্বয়ংক্রিয়ভাবে তৈরি হয়েছিল যখন আমি আনুমানিক পরিকল্পনার জন্য জিজ্ঞাসা করেছি:

DBCC SHOW_STATISTICS('dbo.Posts', [_WA_Sys_00000006_0519C6AF]);

এসএসএমএসে পরিসংখ্যান আউটপুট এর স্ক্রিনশট

এর থেকে হাইলাইটগুলি হ'ল:

  • পরিসংখ্যানগুলির একটি খুব কম নমুনার হার রয়েছে 1.81% (67,796 / 3,744,192)
  • শুধুমাত্র 31 টি হিস্টোগ্রাম পদক্ষেপ ব্যবহার করা হয়েছিল
  • "সমস্ত ঘনত্ব" মান 0.03030303(33 টি স্বতন্ত্র মান নমুনা করা হয়েছিল)
  • 1 RANGE_HI_KEYসহ হিস্টোগ্রামে সর্বশেষ 50 টিEQ_ROWS

প্রশ্ন

50 এর বেশি মান (2,147,483,647 অবধি এবং সহ) ছাড়িয়ে যাওয়া 1,934.99 সারি অনুমানের ফলস্বরূপ। এই হিসেবটি তৈরি করতে কোন গণনা বা মান ব্যবহার করা হয়? লিগ্যাসি কার্ডিনালিটি অনুমানকারী যাইহোক, 1 সারি হিসাবে একটি অনুমান উত্পাদন করে।

আমি কি চেষ্টা করেছি

এখানে আমার কিছু তত্ত্ব রয়েছে, আমি চেষ্টা করেছি এমন জিনিসগুলি বা তথ্যের অতিরিক্ত বিটগুলি এটি অনুসন্ধান করার সময় আমি খনন করতে সক্ষম হয়েছি।

ঘনত্বের ভেক্টর

আমি প্রথমে ভেবেছিলাম এটি ঘনত্বের ভেক্টর হবে, যেমনটি আমি ব্যবহার করেছি OPTION (OPTIMIZE FOR UNKNOWN)। তবে এই পরিসংখ্যান অবজেক্টের জন্য ঘনত্বের ভেক্টরটি 3,744,192 * 0.03030303 = 113,460, তাই এটি নয়।

বর্ধিত ইভেন্টগুলি

আমি একটি বর্ধিত ইভেন্ট সেশন চালানোর চেষ্টা করেছি query_optimizer_estimate_cardinalityযা ইভেন্টটি সংগ্রহ করেছিল (যা আমি পল হোয়াইটের ব্লগ পোস্ট কার্ডিনালাইটি অনুমানের কাছ থেকে শিখেছি : ঘনত্বের পরিসংখ্যানের সমন্বয় ) এবং এই ধরণের আকর্ষণীয় সংবাদ পেয়েছি:

<CalculatorList>
  <FilterCalculator CalculatorName="CSelCalcColumnInInterval" Selectivity="-1.000" 
                    CalculatorFailed="true" TableName="[p]" ColumnName="CommentCount" />

  <FilterCalculator CalculatorName="CSelCalcAscendingKeyFilter" Selectivity="0.001" 
                    TableName="[p]" ColumnName="CommentCount" UseAverageFrequency="true" 
                    StatId="4" />
</CalculatorList>

সুতরাং এটি প্রদর্শিত হয় CSelCalcAscendingKeyFilterক্যালকুলেটর ব্যবহার করা হয়েছিল (অন্যটি বলে যে এটি ব্যর্থ হয়েছে, এর অর্থ যাই হোক না কেন)। এই কলামটি কী বা অদ্বিতীয় নয়, বা অগত্যা আরোহী নয়, যাই হোক না কেন।

এই শব্দটির কিছু গুগলিং করা আমাকে কিছু ব্লগ পোস্টে নিয়ে গেছে:

এই পোস্টগুলি ঘনত্বের ভেক্টর এবং স্টেটের সংশোধন কাউন্টারের সংমিশ্রণে হিস্টগ্রামের বাইরের হিসাবের বাইরে এই নতুন সিই বেসগুলিকে নির্দেশ করে। দুর্ভাগ্যক্রমে, আমি ইতিমধ্যে ঘনত্বের ভেক্টরটিকে বাতিল করে দিয়েছি (আমার মনে হয় ?!), এবং পরিবর্তনের কাউন্টারটি শূন্য ( sys.dm_db_stats_propertiesযাইহোক প্রতি ) is

পতাকাগুলি ট্রেস করুন

ফরেস্ট প্রস্তাব দিয়েছিল যে অনুমান প্রক্রিয়া সম্পর্কে আরও কিছু তথ্য পেতে আমি টিএফ 2363 চালু করি। আমি মনে করি যে আউটপুট থেকে সবচেয়ে প্রাসঙ্গিক জিনিসটি হ'ল:

Plan for computation:

  CSelCalcAscendingKeyFilter(avg. freq., QCOL: [p].CommentCount)

Selectivity: 0.000516798

এটি একটি যুগান্তকারী (ধন্যবাদ, ফরেস্ট!): সেই 0.000516798সংখ্যাটি (যা Selectivity="0.001"উপরের এক্স ই গুণাবলীতে অপ্রয়োজনীয়ভাবে গোল করা হয়েছে বলে মনে হয় ) সারণির সারিগুলির সংখ্যা দ্বারা গুণিত হ'ল আমি যে হিসাবটি খুঁজছিলাম তার অনুমান (1,934.99)।

আমি সম্ভবত সুস্পষ্ট কিছু মিস করছি, তবে আমি কীভাবে CSelCalcAscendingKeyFilterক্যালকুলেটরের অভ্যন্তরে সেলেকটিভিটির মান উত্পন্ন হয় তা আমি প্রকৌশলীকে বিপরীত করতে সক্ষম হইনি ।

উত্তর:


13

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

আপনার ক্ষেত্রে, 1,934.99 = এসকিউআরটি (3744192)

নীচে পরীক্ষার সেটআপ:

--setup
USE TestDB
ALTER DATABASE [TestDB] SET AUTO_UPDATE_STATISTICS OFF
GO

DROP TABLE IF EXISTS dbo.Hist

CREATE TABLE dbo.Hist (
ID int identity primary key,
Num int
)

INSERT dbo.Hist
SELECT TOP 300
(ROW_NUMBER() OVER(ORDER BY(SELECT 1/0)))%3
FROM master..spt_values a
CROSS JOIN master..spt_values b
--Get estimated plan
--don't forget to run right after setup to auto-create stats
SELECT *
FROM dbo.Hist
WHERE Num = 1000
--gradually add rows, then rerun estimate above
INSERT dbo.Hist
SELECT TOP 100
-1
FROM master..spt_values a
--I sure hope you weren't testing this in prod (cleanup)
ALTER DATABASE [TestDB] SET AUTO_UPDATE_STATISTICS ON
GO

আশ্চর্যজনকভাবে এমনকি সারি অনুমানগুলি এই পদ্ধতির থেকে উত্পন্ন হয়েছিল: মোট 400 টি সারিতে 20, 900 এ 30, 40 এ 1600 ইত্যাদি etc.

গত ১০০০০০ সত্ত্বেও, সারিটির প্রাক্কলনটি সর্বাধিক ১০০ ছাড়িয়ে যায় যা বিদ্যমান পরিসংখ্যানগুলিতে মূল্য অনুসারে সারি সংখ্যা। স্কুয়ার্ট (300)> 10 যেহেতু কেবল 10 টি সারি যুক্ত করা হলে অনুমানটি 10 ​​তে সেট করা হবে।

সুতরাং এই সূত্রটি ব্যবহার করে অনুমানগুলি প্রকাশ করা যেতে পারে:

Estimate = MIN(SQRT(AC), MIN(AR, MC))

নোট করুন যে পরিসংখ্যানগুলি নমুনা দেওয়া হয়, তবে এমসিকে বিবেচনা করা হয় না। সূত্রটি হয়ে যায়:

Estimate = MIN(SQRT(AC), AR))

কোথায়

  • এমসি হ'ল "সংশোধন গণনা" (পরিসংখ্যান তৈরির পর থেকে # সংশোধনী)
  • এসি হ'ল "অ্যাডজাস্টেড কার্ডিনালিটি" (পরিসংখ্যান প্লাস এমসির থেকে সারিগুলির #),
  • এআর হ'ল গড় মূল্য সারি (কলামে স্বতন্ত্র মান দ্বারা বিভাজিত পরিসংখ্যান থেকে সারিগুলির #)

এই অনুমানের সূত্রগুলি এবং ক্যালকুলেটর সম্পর্কে অন্যান্য বিশদগুলি এই ব্লগ পোস্টে পাওয়া যাবে: সিএসএলক্যালসএসেন্ডেন্ডিংকিফিল্টার ক্যালকুলেটর থেকে অনুমানের বিশ্লেষণ

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