লাইক অপারেটরের জন্য কার্ডিনালিটির প্রাক্কলন (স্থানীয় ভেরিয়েবল)


24

আমি এই LIKEধারণাটির মধ্যে ছিলাম যে অপারেটরটি সমস্ত ক্ষেত্রে অজানা পরিস্থিতিগুলির জন্য অপ্টিমাইজ করার সময় লেগ্যাসি এবং নতুন সিই উভয়ই 9% প্রাক্কলন ব্যবহার করে (অনুমিত হয় যে প্রাসঙ্গিক পরিসংখ্যান পাওয়া যায় এবং ক্যোয়ারী অপটিমাইজারকে নির্বাচনের অনুমানের আশ্রয় নিতে হয় না)।

ক্রেডিট ডাটাবেসের বিরুদ্ধে নীচের কোয়েরিটি সম্পাদন করার সময় আমি বিভিন্ন সিই এর অধীনে বিভিন্ন অনুমান পাই। নতুন সিই এর অধীনে আমি 900 সারিগুলির একটি অনুমান পাই যা আমি প্রত্যাশা করছিলাম, সিই উত্তরাধিকারের অধীনে আমি 241.416 এর একটি অনুমান পাই এবং এই অনুমানটি কীভাবে উত্পন্ন হয়েছে তা আমি বুঝতে পারি না। কেউ কি কোনও আলো ফেলতে সক্ষম?

-- New CE (Estimate = 900)
DECLARE @LastName VARCHAR(15) = 'BA%'
SELECT * FROM [Credit].[dbo].[member]
WHERE [lastname] LIKE @LastName;

-- Forcing Legacy CE (Estimate = 241.416)
DECLARE @LastName VARCHAR(15) = 'BA%'
SELECT * FROM [Credit].[dbo].[member]
WHERE [lastname] LIKE @LastName
OPTION (
QUERYTRACEON 9481,
QUERYTRACEON 9292,
QUERYTRACEON 9204,
QUERYTRACEON 3604
);

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

আমি এই ইতজিক বেন-গান আর্টিকেল ছাড়া অন্য কিছু খুঁজে পাইনি , যেখানে বলা হয়েছে "LIKE predict ব্যবহার করার পরে সমস্ত ক্ষেত্রে অজানা পরিস্থিতিগুলির জন্য অনুকূলিত হওয়া এবং নতুন সিই উভয়ই 9 শতাংশ অনুমান ব্যবহার করে"। সেই পোস্টের তথ্যটি ভুল বলে মনে হবে।

উত্তর:


28

LIKE আপনার ক্ষেত্রে অনুমানটি এর উপর ভিত্তি করে:

  • G: স্ট্যান্ডার্ড 9% অনুমান ( sqllang!x_Selectivity_Like)
  • M: 6 এর একটি উপাদান (যাদু নম্বর)
  • D: বাইটস (পরিসংখ্যান থেকে) এর গড় ডেটা দৈর্ঘ্য, পূর্ণসংখ্যাতে গোল হয়

বিশেষত, sqllang!CCardUtilSQL7::ProbLikeGuessব্যবহার:

Selectivity (S) = G / M * LOG(D)

নোট:

  • LOG(D)যদি শব্দটি বাদ দেওয়া হয় D1 এবং 2 মধ্যে।
  • যদি D1 এর কম হয় (নিখোঁজ বা NULLপরিসংখ্যান সহ ):
    D = FLOOR(0.5 * maximum column byte length)

এই ধরণের উদাসীনতা এবং জটিলতা মূল সিই এর বেশ সাধারণ।

প্রশ্নের উদাহরণে, গড় দৈর্ঘ্য 5 ( DBCC SHOW_STATISTICSবৃত্তাকার নিচে থেকে 5.6154 ):

প্রাক্কলন = 10,000 * (0.09 / 6 * এলওজি (5)) = 241.416

অন্যান্য উদাহরণের মান:

 ডি   = এস এর সূত্র ব্যবহার করে অনুমান করুন
 15 = 406.208
 14 = 395.859
 13 = 384.742
 12 = 372.736
 11 = 359.684
 10 = 345.388
 09 = 329.584
 08 = 311.916
 07 = 291.887
 06 = 268.764
 05 = 241.416
 04 = 207.944
 03 = 164.792
 02 = 150.000 (এলওজি ব্যবহার করা হয়নি)
 01 = 150.000 (এলওজি ব্যবহার করা হয়নি)
 00 = 291.887 (লগ 7) / * ফ্লোর (0.5 * 15) [15 যেহেতু পদবীকরণের নাম বর্ণের (15)] * /

টেস্ট রিগ

DECLARE
    @CharLength integer = 5, -- Set length here
    @Counter integer = 1;

CREATE TABLE #T (c1 varchar(15) NULL);

-- Add 10,000 rows
SET NOCOUNT ON;
SET STATISTICS XML OFF;

BEGIN TRANSACTION;
WHILE @Counter <= 10000
BEGIN
    INSERT #T (c1) VALUES (REPLICATE('X', @CharLength));
    SET @Counter = @Counter + 1;
END;
COMMIT TRANSACTION;

SET NOCOUNT OFF;
SET STATISTICS XML ON;

-- Test query
DECLARE @Like varchar(15);
SELECT * FROM #T AS T 
WHERE T.c1 LIKE @Like;

DROP TABLE #T;

15

আমি এসকিউএল সার্ভার ২০১৪ সালে উত্তরাধিকারী সিই দিয়ে পরীক্ষা করেছি এবং কার্ডিনালিটির অনুমান হিসাবে 9 %ও পাইনি। আমি অনলাইনে নির্ভুল কিছু খুঁজে পেলাম না তাই আমি কিছু পরীক্ষা করেছি এবং আমি এমন একটি মডেল পেয়েছি যা আমি পরীক্ষার সমস্ত পরীক্ষার ক্ষেত্রে খাপ খায়, তবে আমি নিশ্চিত হতে পারি না যে এটি সম্পূর্ণ হয়েছে।

যে মডেলটি আমি পেয়েছি, তাতে টেবিলের সারি সংখ্যা, ফিল্টারকৃত কলামের পরিসংখ্যানের গড় কী দৈর্ঘ্য এবং কখনও কখনও ফিল্টারকৃত কলামের ডেটাটাইপ দৈর্ঘ্য থেকে অনুমানটি পাওয়া যায়। অনুমানের জন্য দুটি পৃথক সূত্র ব্যবহৃত হয়।

যদি ফ্লোর (গড় কী দৈর্ঘ্য) = 0 হয় তবে অনুমানের সূত্রটি কলামের পরিসংখ্যান উপেক্ষা করে এবং ডেটাটাইপের দৈর্ঘ্যের ভিত্তিতে একটি অনুমান তৈরি করে। আমি কেবল ভর্চার (এন) দিয়ে পরীক্ষা করেছি যাতে এটি সম্ভব হয় যে এনভিচারার (এন) এর জন্য আলাদা একটি সূত্র রয়েছে। ভ্রচার (এন) এর সূত্রটি এখানে:

(সারি অনুমান) = (সারণিতে সারি) * (-0.004869 + 0.032649 * লগ 10 (ডেটা ধরণের দৈর্ঘ্য))

এটিতে খুব সুন্দর ফিট রয়েছে তবে এটি পুরোপুরি সঠিক নয়:

প্রথম সূত্র গ্রাফ

এক্স-অক্ষটি হ'ল ডেটা টাইপের দৈর্ঘ্য এবং y অক্ষটি 1 মিলিয়ন সারি সহ একটি সারণীর জন্য অনুমান সারিগুলির সংখ্যা।

ক্যোয়ারী অপ্টিমাইজার এই সূত্রটি ব্যবহার করবে যদি আপনার কলামে পরিসংখ্যান না থাকে বা কলামে যদি মূল কী দৈর্ঘ্য 1 এর নীচে চালিত করতে পর্যাপ্ত NULL মান থাকে।

উদাহরণস্বরূপ, ধরুন যে আপনি একটি VARCHAR (50) এ ফিল্টারিং সহ 150k সারি সহ একটি টেবিল রেখেছিলেন এবং কোনও কলামের পরিসংখ্যান নেই। সারি অনুমানের পূর্বাভাসটি হ'ল:

150000 * (-0.004869 + 0.032649 * লগ 10 (50)) = 7590.1 সারি

এটি পরীক্ষার জন্য এসকিউএল:

CREATE TABLE X_CE_LIKE_TEST_1 (
STRING VARCHAR(50)
);

CREATE STATISTICS X_STAT_CE_LIKE_TEST_1 ON X_CE_LIKE_TEST_1 (STRING) WITH NORECOMPUTE;

WITH
    L0 AS (SELECT 1 AS c UNION ALL SELECT 1),
    L1 AS (SELECT 1 AS c FROM L0 A CROSS JOIN L0 B),
    L2 AS (SELECT 1 AS c FROM L1 A CROSS JOIN L1 B),
    L3 AS (SELECT 1 AS c FROM L2 A CROSS JOIN L2 B),
    L4 AS (SELECT 1 AS c FROM L3 A CROSS JOIN L3 B CROSS JOIN L2 C),
    NUMS AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS NUM FROM L4)  
    INSERT INTO X_CE_LIKE_TEST_1 WITH (TABLOCK) (STRING)
    SELECT TOP (150000) 'ZZZZZ'
    FROM NUMS
    ORDER BY NUM;

DECLARE @LastName VARCHAR(15) = 'BA%'
SELECT * FROM X_CE_LIKE_TEST_1
WHERE STRING LIKE @LastName;

এসকিউএল সার্ভারটি 7242.47 এর একটি অনুমানের সারি গণনা দেয় যা এক ধরণের কাছাকাছি।

যদি FLOOR (গড় কী দৈর্ঘ্য)> = 1 হয় তবে একটি আলাদা সূত্র ব্যবহার করা হয় যা FLOOR (গড় কী দৈর্ঘ্যের) মানের উপর ভিত্তি করে তৈরি হয়। এখানে চেষ্টা করা কয়েকটি মানের একটি টেবিল এখানে দেওয়া হয়েছে:

1    1.5%
2    1.5%
3    1.64792%
4    2.07944%
5    2.41416%
6    2.68744%
7    2.91887%
8    3.11916%
9    3.29584%
10   3.45388%

যদি ফ্লোর (গড় কী দৈর্ঘ্য) <6 তবে উপরের সারণীটি ব্যবহার করুন। অন্যথায় নিম্নলিখিত সমীকরণটি ব্যবহার করুন:

(সারি অনুমান) = (সারণিতে সারি) * (-0.003381 + 0.034539 * লগ 10 (ফ্লোর (গড় মূল দৈর্ঘ্য)))

এই একের সাথে অন্যের চেয়ে ভাল ফিট রয়েছে তবে এটি এখনও পুরোপুরি সঠিক নয়।

দ্বিতীয় সূত্র গ্রাফ

এক্স-অক্ষটি হ'ল গড় কী দৈর্ঘ্য এবং y অক্ষটি 1 মিলিয়ন সারি সহ একটি টেবিলের জন্য আনুমানিক সারিগুলির সংখ্যা।

অন্য একটি উদাহরণ দেওয়ার জন্য, ধরুন আপনি ফিল্টারকৃত কলামে পরিসংখ্যানগুলির জন্য 5.5 দৈর্ঘ্যের গড় কী দৈর্ঘ্য সহ 10 কে সারি সহ একটি টেবিল রেখেছিলেন। সারি অনুমানটি হবে:

10000 * 0.241416 = 241.416 সারি।

এটি পরীক্ষার জন্য এসকিউএল:

CREATE TABLE X_CE_LIKE_TEST_2 (
STRING VARCHAR(50)
);

WITH
    L0 AS (SELECT 1 AS c UNION ALL SELECT 1),
    L1 AS (SELECT 1 AS c FROM L0 A CROSS JOIN L0 B),
    L2 AS (SELECT 1 AS c FROM L1 A CROSS JOIN L1 B),
    L3 AS (SELECT 1 AS c FROM L2 A CROSS JOIN L2 B),
    L4 AS (SELECT 1 AS c FROM L3 A CROSS JOIN L3 B CROSS JOIN L2 C),
    NUMS AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS NUM FROM L4)  
    INSERT INTO X_CE_LIKE_TEST_2 WITH (TABLOCK) (STRING)
    SELECT TOP (10000) 
    CASE 
      WHEN NUM % 2 = 1 THEN REPLICATE('Z', 5) 
      ELSE REPLICATE('Z', 6)
    END
    FROM NUMS
    ORDER BY NUM;

CREATE STATISTICS X_STAT_CE_LIKE_TEST_2 ON X_CE_LIKE_TEST_2 (STRING) 
WITH NORECOMPUTE, FULLSCAN;

DECLARE @LastName VARCHAR(15) = 'BA%'
SELECT * FROM X_CE_LIKE_TEST_2
WHERE STRING LIKE @LastName;

সারিটির প্রাক্কলন 241.416 যা আপনার প্রশ্নের সাথে মিল রয়েছে matches আমি টেবিলে মান না ব্যবহার করে কিছু ত্রুটি ঘটবে।

এখানকার মডেলগুলি নিখুঁত নয় তবে আমি মনে করি তারা সাধারণ আচরণটি বেশ ভালভাবে বর্ণনা করেছেন।

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