সেটআপ
একটি কার্ডিনালিটি অনুমান বুঝতে আমার কিছুটা সমস্যা হচ্ছে। এখানে আমার পরীক্ষার সেটআপ:
- স্ট্যাক ওভারফ্লো ডাটাবেসের 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
ক্যালকুলেটর ব্যবহার করা হয়েছিল (অন্যটি বলে যে এটি ব্যর্থ হয়েছে, এর অর্থ যাই হোক না কেন)। এই কলামটি কী বা অদ্বিতীয় নয়, বা অগত্যা আরোহী নয়, যাই হোক না কেন।
এই শব্দটির কিছু গুগলিং করা আমাকে কিছু ব্লগ পোস্টে নিয়ে গেছে:
- জো স্যাক - দ্য 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
ক্যালকুলেটরের অভ্যন্তরে সেলেকটিভিটির মান উত্পন্ন হয় তা আমি প্রকৌশলীকে বিপরীত করতে সক্ষম হইনি ।