এসকিউএল সার্ভার কেন এমন একটি অনুমান নিয়ে আসে যা পরিসংখ্যানগুলির সাথে এতটা বেমানান বলে প্রমাণিত হতে পারে তা বুঝতে আমার খুব কষ্ট হচ্ছে I
দৃঢ়তা
ধারাবাহিকতার কোনও সাধারণ গ্যারান্টি নেই। বিভিন্ন পরিসংখ্যানগত পদ্ধতি ব্যবহার করে বিভিন্ন সময়ে বিভিন্ন (তবে যৌক্তিক সমতুল্য) সাবট্রিতে অনুমানগুলি গণনা করা যেতে পারে।
এই যুক্তিতে কোনও ভুল নেই যে বলে যে এই দুটি অভিন্ন সাবট্রিতে যোগ দেওয়ার জন্য ক্রস পণ্য তৈরি করা উচিত, তবে যুক্তি বাছাইয়ের পছন্দ অন্য যে কোনটির চেয়ে বেশি সুসংবাদযুক্ত বলে সমান কিছুই নেই।
প্রাথমিক অনুমান
আপনার নির্দিষ্ট ক্ষেত্রে, যোগদানের জন্য প্রাথমিক কার্ডিনালিটি অনুমান দুটি অভিন্ন সাবট্রির উপর সম্পাদিত হয় না । সেই সময় গাছের আকার:
LogOp_Join
LogOp_GbAgg
LogOp_LeftOuterJoin
লগঅপ_গীত টিবিএল: আর
LogOp_Select
লগঅপ_গীত টিবিএল: টিসিআর
ScaOp_Comp x_cmpEq
ScaOp_Identifier [tcr] .rId
ScaOp_Const মান = 508
ScaOp_Logical x_lopAnd
ScaOp_Comp x_cmpEq
ScaOp_Identifier [ar] .fId
ScaOp_Identifier [tcr] .fId
ScaOp_Comp x_cmpEq
ScaOp_Identifier [আরবি] .বিড
ScaOp_Identifier [tcr] .বিড
AncOp_PrjList
AncOp_PrjEl Expr1003
ScaOp_AggFunc স্টপম্যাক্স
ScaOp_Convers int
ScaOp_Identifier [tcr] .ISS
LogOp_Select
LogOp_GbAgg
LogOp_LeftOuterJoin
লগঅপ_গীত টিবিএল: আর
LogOp_Select
লগঅপ_গীত টিবিএল: টিসিআর
ScaOp_Comp x_cmpEq
ScaOp_Identifier [tcr] .rId
ScaOp_Const মান = 508
ScaOp_Logical x_lopAnd
ScaOp_Comp x_cmpEq
ScaOp_Identifier [ar] .fId
ScaOp_Identifier [tcr] .fId
ScaOp_Comp x_cmpEq
ScaOp_Identifier [আরবি] .বিড
ScaOp_Identifier [tcr] .বিড
AncOp_PrjList
AncOp_PrjEl Expr1006
ScaOp_AggFunc স্টপমিন
ScaOp_Convers int
ScaOp_Identifier [আরবি] .আইএসটি
AncOp_PrjEl Expr1007
ScaOp_AggFunc স্টপম্যাক্স
ScaOp_Convers int
ScaOp_Identifier [tcr] .ISS
ScaOp_Comp x_cmpEq
ScaOp_Identifier Expr1006
ScaOp_Const মান = 1
ScaOp_Comp x_cmpEq
ScaOp_Identifier QCOL: [ar] .fId
ScaOp_Identifier QCOL: [ar] .fId
প্রথম যোগদানের ইনপুটটিতে একটি অপ্রক্রোজিত সমষ্টি খুব সহজ সরল হয়ে গেছে, এবং দ্বিতীয় যোগদানের ইনপুটটির নীচে প্রাকটিকটি t.isT = 1
ধাক্কা দেওয়া হয়েছে, যেখানে t.isT
রয়েছে MIN(CONVERT(INT, ar.isT))
। এটি সত্ত্বেও, isT
প্রিডিকেটের জন্য নির্বাচিতকরণ গণনা CSelCalcColumnInInterval
একটি হিস্টোগ্রামে ব্যবহার করতে সক্ষম :
CSelCalcColumnInInterval
কলাম: COL: Expr1006
QCOL কলামের জন্য হিস্টোগ্রাম লোড করা হয়েছে: [আরবী ভাষায়]। আইডি 3 সহ পরিসংখ্যানগুলি থেকে শুরু করুন
নির্বাচনীকরণ: 4.85248e-005
পরিসংখ্যান সংগ্রহ উত্পন্ন:
CStCollFilter (আইডি = 11, কার্ড = 1)
CStCollGroupBy (আইডি = 10, কার্ড = 20608)
সিএসটিকোলআউটারজাইন (আইডি = 9, কার্ড = 20608 এক্স_জেট লেফট আউট)
CStCollBaseTable (আইডি = 3, কার্ড = 20608 টিবিএল: আর)
সিএসটিকোলফিল্টার (আইডি = 8, কার্ড = 1)
CStCollBaseTable (ID = 4, CARD = 28 TBL: tcr)
(সঠিক) প্রত্যাশাটি 20,608 টি সারিটির জন্য এই ভবিষ্যদ্বাণীটির মাধ্যমে 1 টি সারিতে হ্রাস পাবে।
অনুমান যোগদান করুন
অন্যান্য প্রশ্নে যোগ দেওয়া ইনপুট থেকে 20,608 সারি এই এক সারির সাথে কীভাবে মিলবে তা এখন প্রশ্নটি হয়ে ওঠে:
LogOp_Join
CStCollGroupBy (আইডি = 7, কার্ড = 20608)
সিএসটিকোলআউটারজাইন (আইডি = 6, কার্ড = 20608 এক্স_জেট লেফট আউটার)
...
CStCollFilter (আইডি = 11, কার্ড = 1)
CStCollGroupBy (আইডি = 10, কার্ড = 20608)
...
ScaOp_Comp x_cmpEq
ScaOp_Identifier QCOL: [ar] .fId
ScaOp_Identifier QCOL: [ar] .fId
সাধারণভাবে যোগদানের অনুমান করার বিভিন্ন উপায় রয়েছে। আমরা উদাহরণস্বরূপ:
- প্রতিটি সাবট্রির প্রতিটি প্ল্যান অপারেটরে নতুন হিস্টোগ্রামগুলি আবিষ্কার করুন, তাদের যোগদানের জন্য সারিবদ্ধ করুন (প্রয়োজনীয় হিসাবে ধাপের মানগুলি পৃথক করে) এবং দেখুন কীভাবে তারা মিলছে; অথবা
- হিস্টোগ্রামগুলির একটি সরল 'মোটা' প্রান্তিককরণ সম্পাদন করুন (ন্যূনতম এবং সর্বাধিক মান ব্যবহার করে, ধাপে নয় ধাপে); অথবা
- একা জোড় কলামগুলির জন্য পৃথক নির্বাণগুলি গণনা করুন (বেস টেবিল থেকে এবং কোনও ফিল্টারিং ছাড়াই), তারপরে নন-জেন প্রিডিটিক (গুলি) এর সিলেকটিভিটি এফেক্ট যুক্ত করুন।
- ...
ব্যবহারে কার্ডিনালিটি অনুমানকারী এবং কিছু হিউরিস্টিকের উপর নির্ভর করে, সেগুলির (বা কোনও প্রকরণ) যে কোনওটি ব্যবহার করা যেতে পারে। আরও তথ্যের জন্য এসকিউএল সার্ভার 2014 কার্ডিনালিটির অনুমানের সাহায্যে মাইক্রোসফ্ট হোয়াইট পেপার আপনার প্রশ্নের পরিকল্পনাগুলি অনুকূল করে দেখুন।
বাগ?
এখন, প্রশ্নে উল্লিখিত হিসাবে, এক্ষেত্রে 'সাধারণ' একক-কলামে যোগদান (চালু fId
) CSelCalcExpressionComparedToExpression
ক্যালকুলেটর ব্যবহার করে :
গণনার পরিকল্পনা:
CSelCalcExpressionCompareToExpression [ar] .f xd_cmpEq [ar] .fId
QCOL কলামের জন্য হিস্টগ্রাম লোড করা হয়েছে: [আরবি] .বি আইডি 2 সহ পরিসংখ্যানগুলি থেকে আইড করুন
কিউসিওএল কলামের জন্য হিস্টগ্রাম লোড করা হয়েছে: [আরবী ভাষায়]। আইডি 1 সহ পরিসংখ্যানগুলি থেকে আইডি
নির্বাচনীকরণ: 0
এই গণনাটি নির্ধারণ করে যে 1 টি ফিল্টার করা সারি সহ 20,608 সারিগুলিতে যোগদানের একটি শূন্য নির্বাচন রয়েছে: কোনও সারি মেলে না (চূড়ান্ত পরিকল্পনার এক সারি হিসাবে রিপোর্ট করা)। এটা কি ভুল? হ্যাঁ, সম্ভবত এখানে নতুন সিইতে একটি বাগ রয়েছে। যে কেউ তর্ক করতে পারে যে 1 সারিটি সমস্ত সারি বা কোনওটির সাথে মিলবে না, সুতরাং ফলাফলটি যুক্তিযুক্ত হতে পারে তবে অন্যথায় বিশ্বাস করার কারণ রয়েছে।
বিশদটি আসলে কৌতূহলোদ্দীপক, তবে অনুমানের প্রত্যাশাটি fId
ফিলিফ্টের সিলেকটিভিটি দ্বারা সংশোধিত, 20608 * 20608 * 4.85248e-005 = 20608
সারি দেওয়া সারণী খণ্ডিত হিস্টোগ্রামের উপর ভিত্তি করে করা খুব যুক্তিসঙ্গত।
এই গণনা অনুসরণ করার অর্থ CSelCalcSimpleJoinWithDistinctCounts
পরিবর্তে ক্যালকুলেটর ব্যবহার করা CSelCalcExpressionComparedToExpression
। এটি করার জন্য কোনও নথিভুক্ত উপায় নেই তবে আপনি যদি আগ্রহী হন তবে আপনি অনাবন্ধিত ট্রেস পতাকা 9479 সক্ষম করতে পারেন:
নোট করুন চূড়ান্ত যোগদানটি দুটি একক-সারি ইনপুট থেকে 20,608 সারি তৈরি করে, তবে এটি আশ্চর্য হওয়া উচিত নয়। এটি টিএফ 9481 এর অধীনে মূল সিই দ্বারা উত্পাদিত একই পরিকল্পনা।
আমি বিশদটি জটিল এবং (তদন্তে সময়সাপেক্ষ) উল্লেখ করেছি, তবে যতদূর আমি বলতে পারি সমস্যার মূল কারণটি rId = 508
শূন্যতার সাথে নির্বাচনী ভবিষ্যতের সাথে সম্পর্কিত । এই শূন্য প্রাক্কলনটি স্বাভাবিক উপায়ে এক সারিতে উত্থাপিত হয়, যা ইনপুট ট্রিটিতে নিম্ন পূর্বাভাসের জন্য অ্যাকাউন্ট হয়ে থাকে (সুতরাং এর জন্য পরিসংখ্যান লোড করা হয় bId
) যখন প্রশ্নটিতে যোগ দেওয়ার সময় শূন্য নির্বাচনের অনুমানকে অবদান রাখে বলে মনে হয় ।
বাইরের জোড়কে শূন্য-সারির অভ্যন্তরীণ পার্শ্বের অনুমান রাখতে দেওয়া (এক সারিতে উত্থাপনের পরিবর্তে) (সুতরাং সমস্ত বাহ্যিক সারিগুলি যোগ্য) ক্যালকুলেটরের সাথে একটি 'বাগ-মুক্ত' যোগদানের অনুমান দেয় join আপনি যদি এটি অন্বেষণ করতে আগ্রহী হন, অনির্ধারিত ট্রেস পতাকাটি 9473 (একা):
এর CSelCalcExpressionComparedToExpression
সাথে জোড় কার্ডিনালিটি অনুমানের আচরণটি অন্য একটি নথিভুক্ত প্রকরণের পতাকা (9494) দিয়ে `` bId` এর জন্য অ্যাকাউন্ট না করেও সংশোধন করা যেতে পারে। আমি এই সমস্ত উল্লেখ করছি কারণ আমি জানি যে এই জাতীয় বিষয়ে আপনার আগ্রহ আছে; তারা সমাধান প্রস্তাব না কারণ। যতক্ষণ না আপনি মাইক্রোসফ্টকে সমস্যাটি প্রতিবেদন করেন এবং তারা এটিকে সম্বোধন করে (বা না), ক্যোয়ারিকে আলাদাভাবে প্রকাশ করা সম্ভবত এগিয়ে যাওয়ার সেরা উপায়। আচরণটি ইচ্ছাকৃত হোক বা না থাকুক না কেন, তারা রিগ্রেশন সম্পর্কে শুনতে আগ্রহী হওয়া উচিত।
পরিশেষে, প্রজনন স্ক্রিপ্টে উল্লিখিত অন্য একটি জিনিসকে পরিষ্কার করার জন্য: প্রশ্ন পরিকল্পনার মধ্যে ফিল্টারটির চূড়ান্ত অবস্থানটি ব্যয়ভিত্তিক অন্বেষণের GbAggAfterJoinSel
ফলে জন্ডের উপরে সামগ্রিক এবং ফিল্টার সঞ্চারিত হয়, যেহেতু জোড় আউটপুটটির এত ছোট থাকে সারির সংখ্যা. ফিল্টারটি প্রাথমিকভাবে যোগদানের নীচে ছিল, যেমনটি আপনি প্রত্যাশা করেছিলেন।