কেন লেন () এসকিউএল সার্ভার 2014 এ খারাপভাবে কম মূল্যায়ন করবে না?


26

আমার কাছে একটি স্ট্রিং কলাম সহ একটি টেবিল রয়েছে এবং একটি প্রিকিকেট যা নির্দিষ্ট দৈর্ঘ্য সহ সারিগুলির জন্য পরীক্ষা করে। এসকিউএল সার্ভার ২০১৪-তে, আমি যে দৈর্ঘ্যের জন্য যাচাই করছি তা নির্বিশেষে 1 টি সারির অনুমান দেখছি। এটি অত্যন্ত দুর্বল পরিকল্পনা গ্রহণ করছে কারণ সেখানে হাজার হাজার বা এমনকি কয়েক মিলিয়ন সারি রয়েছে এবং এসকিউএল সার্ভার এই টেবিলটিকে নেস্টেড লুপের বাইরের দিকে রাখতে পছন্দ করছে to

এসকিউএল সার্ভার ২০১৪-এর এসকিউএল সার্ভার ২০১২-এর 31,622 সারিগুলির অনুমানের জন্য 1.0003 এর কার্ডিনালিটির প্রাক্কলনের জন্য কোনও ব্যাখ্যা আছে কি? একটি ভাল workaround আছে?

এখানে ইস্যুটির একটি সংক্ষিপ্ত প্রজনন:

-- Create a table with 1MM rows of dummy data
CREATE TABLE #customers (cust_nbr VARCHAR(10) NOT NULL)
GO

INSERT INTO #customers WITH (TABLOCK) (cust_nbr)
    SELECT TOP 1000000 
        CONVERT(VARCHAR(10),
        ROW_NUMBER() OVER (ORDER BY (SELECT NULL))) AS cust_nbr
    FROM master..spt_values v1
    CROSS JOIN master..spt_values v2
GO

-- Looking for string of a certain length.
-- While both CEs yield fairly poor estimates, the 2012 CE is much
-- more conservative (higher estimate) and therefore much more likely
-- to yield an okay plan rather than a drastically understimated loop join.
-- 2012: 31,622 rows estimated, 900K rows actual
-- 2014: 1 row estimated, 900K rows actual
SELECT COUNT(*)
FROM #customers
WHERE LEN(cust_nbr) = 6
OPTION (QUERYTRACEON 9481) -- Optionally, use 2012 CE
GO

এখানে অতিরিক্ত পরীক্ষাগুলি দেখানো আরও একটি সম্পূর্ণ স্ক্রিপ্ট

আমি এসকিউএল সার্ভার ২০১৪ কার্ডিনালিটি এসটিমেটরের শ্বেতপত্রটিও পড়েছি , তবে সেখানে পরিস্থিতি স্পষ্ট করে এমন কোনও কিছুই পাইনি।

উত্তর:


20

উত্তরাধিকার সিই জন্য, আমি দেখতে অনুমান সারির 3,16228% জন্য - এবং যে একটি "ম্যাজিক নম্বর" কলামটিতে ব্যবহৃত অনুসন্ধানমূলক = আক্ষরিক predicates (অন্যান্য সম্পৃক্ত নির্মাণ উপর ভিত্তি করে হিউরিস্টিক হয় - কিন্তু LENজন্য কলাম প্রায় আবৃত লেগ্যাসি সিই ফলাফল এই অনুমান-কাঠামোর সাথে মেলে)। আপনি জো স্যাকের পরিসংখ্যানের অনুপস্থিতিতে সিলেকটিভিটি অনুমানের একটি পোস্টে এবং ইয়ান জোসের কনস্ট্যান্ট-কনস্ট্যান্ট তুলনা অনুমানের পোস্টে এর উদাহরণগুলি দেখতে পাবেন ।

-- Legacy CE: 31622.8 rows
SELECT  COUNT(*)
FROM    #customers
WHERE   LEN(cust_nbr) = 6
OPTION  ( QUERYTRACEON 9481); -- Legacy CE
GO

নতুন সিই আচরণের ক্ষেত্রে এখন মনে হচ্ছে এটি এখন অপটিমাইজারের কাছে দৃশ্যমান (যার অর্থ আমরা পরিসংখ্যান ব্যবহার করতে পারি)। আমি নীচে ক্যালকুলেটর আউটপুট দেখার অনুশীলনটি দিয়েছিলাম এবং আপনি সম্পর্কিত পয়েন্টার হিসাবে পরিসংখ্যান সম্পর্কিত স্ব-প্রজন্মের দিকে নজর দিতে পারেন:

-- New CE: 1.00007 rows
SELECT  COUNT(*)
FROM    #customers
WHERE   LEN(cust_nbr) = 6
OPTION  ( QUERYTRACEON 2312 ); -- New CE
GO

-- View New CE behavior with 2363 (for supported option use XEvents)
SELECT  COUNT(*)
FROM    #customers
WHERE   LEN(cust_nbr) = 6
OPTION  (QUERYTRACEON 2312, QUERYTRACEON 2363, QUERYTRACEON 3604, RECOMPILE); -- New CE
GO

/*
Loaded histogram for column QCOL:
[tempdb].[dbo].[#customers].cust_nbr from stats with id 2
Using ambient cardinality 1e+006 to combine distinct counts:
  999927

Combined distinct count: 999927
Selectivity: 1.00007e-006
Stats collection generated:
  CStCollFilter(ID=2, CARD=1.00007)
      CStCollBaseTable(ID=1, CARD=1e+006 TBL: #customers)

End selectivity computation
*/

EXEC tempdb..sp_helpstats '#customers';


--Check out AVG_RANGE_ROWS values (for example - plenty of ~ 1)
DBCC SHOW_STATISTICS('tempdb..#customers', '_WA_Sys_00000001_B0368087');
--That's my Stats name yours is subject to change

দুর্ভাগ্যক্রমে যুক্তিটি স্বতন্ত্র মানগুলির সংখ্যার একটি প্রাক্কলনের উপর নির্ভর করে, যা LENফাংশনের প্রভাবের জন্য সামঞ্জস্য হয় না ।

সম্ভাব্য কাজ

আপনি দুটি সিই মডেলের অধীনে LENএকটি হিসাবে আবারও লিখে ত্রি-ভিত্তিক অনুমান পেতে পারেন LIKE:

SELECT COUNT_BIG(*)
FROM #customers AS C
WHERE C.cust_nbr LIKE REPLICATE('_', 6);

পরিকল্পনা মত


ব্যবহৃত ট্রেস পতাকা সম্পর্কিত তথ্য:

  • 2363: পরিসংখ্যান লোড হচ্ছে সহ অনেক তথ্য দেখায়।
  • 3604: বার্তা ট্যাবে DBCC কমান্ডের আউটপুট মুদ্রণ করে।

13

এসকিউএল ২০১৪-এর জন্য এসকিউএল ২০১২-এর 31,622 টি সারি অনুমানের কার্ডিনালিটি প্রাক্কলনের জন্য কোনও ব্যাখ্যা আছে কি?

আমি মনে করি @ জেনের উত্তরটি এই অংশটি বেশ ভালভাবে কভার করেছে।

একটি ভাল workaround আছে?

আপনি এই গণিত কলামে একটি অনাহীন গণিত কলাম তৈরি করার চেষ্টা করতে পারেন LEN(cust_nbr)এবং ( allyচ্ছিকভাবে ) একটি ক্লাস্টারযুক্ত সূচক তৈরি করতে পারেন। এটি আপনার সঠিক পরিসংখ্যান পাওয়া উচিত।

আমি কিছু পরীক্ষা করেছি এবং আমি এখানে যা পেয়েছি তা এখানে:

  • পরিসংখ্যানগুলি অ-নিরস্তিত গণিত কলামে স্বয়ংক্রিয়ভাবে তৈরি করা হয়েছিল, যখন তার উপর কোনও সূচক সংজ্ঞায়িত করা হয়নি।
  • গণনা করা কলামে নন-ক্লাস্টারড ইনডেক্স যুক্ত করা কেবল সহায়তা করে না, এটি কার্য সম্পাদনকে একটু আঘাত করে। সামান্য উচ্চতর সিপিইউ এবং অতিবাহিত সময়গুলি। সামান্য উচ্চতর আনুমানিক ব্যয় (যাই হোক না কেন এটি মূল্য)।
  • PERSISTEDঅন্যান্য দুটি প্রকরণের তুলনায় (কোনও সূচক নয়) হিসাবে গণিত কলাম তৈরি করা ভাল। আনুমানিক সারিগুলি আরও সঠিক ছিল। সিপিইউ এবং অতিবাহিত সময় ভাল ছিল (যেমন প্রত্যাশা হিসাবে এটি প্রতি সারিতে কিছু গণনা করতে হয়নি)।
  • আমি গণিত কলামে ফিল্টার সূচক বা ফিল্টার পরিসংখ্যান তৈরি করতে অক্ষম ছিলাম (এটি গণনা করার কারণে), যদিও তা ছিল PERSISTED:-(

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