মাল্টি স্টেটমেন্ট টিভিএফ বনাম ইনলাইন টিভিএফ পারফরম্যান্স


18

প্যালিনড্রোম প্রশ্নের উত্তরগুলির সাথে কিছু তুলনা করা হচ্ছে (10k + ব্যবহারকারী কেবলমাত্র, যেহেতু আমি উত্তরটি মুছে ফেলেছি), আমি বিভ্রান্তিকর ফলাফল পাচ্ছি।

আমি একটি মাল্টি-স্টেটমেন্ট, স্কিমা-সীমাবদ্ধ টিভিএফ প্রস্তাব করেছি যা আমি ভেবেছিলাম যে এটি কোনও স্ট্যান্ডার্ড ফাংশন চালানোর চেয়ে দ্রুত হবে which আমি এই ধারণার মধ্যেও ছিলাম যে মাল্টি-স্টেটমেন্ট টিভিএফ "ইনলাইনড" হবে, যদিও আমি সেই গণনায় ভুল, আপনি নীচে দেখতে পাবেন। এই প্রশ্নটি টিভিএফের এই দুটি শৈলীর পারফরম্যান্স পার্থক্য সম্পর্কে। প্রথমত, আপনাকে কোডটি দেখতে হবে।

এখানে মাল্টি-স্টেটমেন্ট টিভিএফ:

IF OBJECT_ID('dbo.IsPalindrome') IS NOT NULL
DROP FUNCTION dbo.IsPalindrome;
GO
CREATE FUNCTION dbo.IsPalindrome
(
    @Word NVARCHAR(500)
) 
RETURNS @t TABLE
(
    IsPalindrome BIT NOT NULL
)
WITH SCHEMABINDING
AS
BEGIN
    DECLARE @IsPalindrome BIT;
    DECLARE @LeftChunk NVARCHAR(250);
    DECLARE @RightChunk NVARCHAR(250);
    DECLARE @StrLen INT;
    DECLARE @Pos INT;
    SET @RightChunk = '';
    SET @IsPalindrome = 0;
    SET @StrLen = LEN(@Word) / 2;
    IF @StrLen % 2 = 1 SET @StrLen = @StrLen - 1;
    SET @Pos = LEN(@Word);
    SET @LeftChunk = LEFT(@Word, @StrLen);
    WHILE @Pos > (LEN(@Word) - @StrLen)
    BEGIN
        SET @RightChunk = @RightChunk + SUBSTRING(@Word, @Pos, 1)
        SET @Pos = @Pos - 1;
    END
    IF @LeftChunk = @RightChunk SET @IsPalindrome = 1;
    INSERT INTO @t VALUES (@IsPalindrome);
    RETURN
END
GO

ইনলাইন-টিভিএফ:

IF OBJECT_ID('dbo.InlineIsPalindrome') IS NOT NULL
DROP FUNCTION dbo.InlineIsPalindrome;
GO
CREATE FUNCTION dbo.InlineIsPalindrome
(
    @Word NVARCHAR(500)
)
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN (
    WITH Nums AS
    (
      SELECT
        N = number
      FROM
        dbo.Numbers
    )
    SELECT
      IsPalindrome =
        CASE
          WHEN EXISTS
          (
            SELECT N
            FROM Nums
            WHERE N <= L / 2
              AND SUBSTRING(S, N, 1) <> SUBSTRING(S, 1 + L - N, 1)
          )
          THEN 0
          ELSE 1
        END
    FROM
      (SELECT LTRIM(RTRIM(@Word)), LEN(@Word)) AS v (S, L)
);
GO

Numbersউপরের ফাংশন টেবিল হিসাবে সংজ্ঞায়িত করা হয়:

CREATE TABLE dbo.Numbers
(
    Number INT NOT NULL 
);

দ্রষ্টব্য: সংখ্যা সারণীতে কোনও সূচী নেই এবং কোনও প্রাথমিক কী নেই এবং এতে 1,000,000 সারি রয়েছে।

একটি পরীক্ষার শয্যা অস্থায়ী টেবিল:

IF OBJECT_ID('tempdb.dbo.#Words') IS NOT NULL
DROP TABLE #Words;
GO
CREATE TABLE #Words 
(
    Word VARCHAR(500) NOT NULL
);

INSERT INTO #Words(Word) 
SELECT o.name + REVERSE(w.name)
FROM sys.objects o
CROSS APPLY (
    SELECT o.name
    FROM sys.objects o
) w;

আমার পরীক্ষা সিস্টেমে উপরের INSERTফলাফলগুলিতে 16,900 সারি #Wordsসারণিতে সন্নিবেশ করা হচ্ছে ।

দুটি ভিন্নতা পরীক্ষা করতে, আমি SET STATISTICS IO, TIME ON;এবং নিম্নলিখিতটি ব্যবহার করি :

SELECT w.Word
    , p.IsPalindrome
FROM #Words w
    CROSS APPLY dbo.IsPalindrome(w.Word) p
ORDER BY w.Word;


SELECT w.Word
    , p.IsPalindrome
FROM #Words w
    CROSS APPLY dbo.InlineIsPalindrome(w.Word) p
ORDER BY w.Word;

আমি প্রত্যাশা করেছিলাম InlineIsPalindromeসংস্করণটি দ্রুততর হবে, তবে নিম্নলিখিত ফলাফলগুলি এই ধারণাটিকে সমর্থন করে না।

মাল্টি-স্টেটমেন্ট টিভিএফ:

সারণী '# A1CE04C3'। স্ক্যানের গণনা 16896, লজিকাল পড়ছে 16900, শারীরিক 0 টি, পঠন-এগিয়ে 0, লব লজিকাল 0, লব ফিজিকাল 0, লব রিড-
ফরোয়ার্ড 0 টেবিল 'ওয়ার্কটেবল'। স্ক্যান কাউন্ট 0, লজিকাল রিড 0, ফিজিকাল রিড 0, রিড-ফরোডড রিড 0, লব লজিকাল রিড 0, লব ফিজিকাল রিড 0, লব রিড-
ফরোয়ার্ড 0 টেবিল '# ওয়ার্ডস'। স্ক্যান কাউন্ট 1, লজিকাল রিড 88, ফিজিকাল রিড 0, রিড-ফরোডড রিড 0, লব লজিকাল রিড 0, লব ফিজিকাল 0, লব রিড-ফরোয়ার্ড 0

এসকিউএল সার্ভার এক্সিকিউশন টাইমস:
সিপিইউ সময় = 1700 এমএস, অতিবাহিত সময় = 2022 এমএস।
এসকিউএল সার্ভার পার্স এবং সংকলনের সময়:
সিপিইউ সময় = 0 এমএস, বিগত সময় = 0 এমএস।

ইনলাইন টিভিএফ:

সারণী 'নম্বর'। স্ক্যান কাউন্ট 1, লজিকাল 1272030, শারীরিক 0, রিড-ফরোডড 0, লব লজিকাল রিড 0, লব ফিজিকাল 0, লব রিড-
ফরোয়ার্ড 0 টেবিল 'ওয়ার্কটেবল'। স্ক্যান কাউন্ট 0, লজিকাল রিড 0, ফিজিকাল রিড 0, রিড-ফরোডড রিড 0, লব লজিকাল রিড 0, লব ফিজিকাল রিড 0, লব রিড-
ফরোয়ার্ড 0 টেবিল '# ওয়ার্ডস'। স্ক্যান কাউন্ট 1, লজিকাল রিড 88, ফিজিকাল রিড 0, রিড-ফরোডড রিড 0, লব লজিকাল রিড 0, লব ফিজিকাল 0, লব রিড-ফরোয়ার্ড 0

এসকিউএল সার্ভার এক্সিকিউশন টাইমস:
সিপিইউ সময় = 137874 এমএস, অতিবাহিত সময় = 139415 এমএস।
এসকিউএল সার্ভার পার্স এবং সংকলনের সময়:
সিপিইউ সময় = 0 এমএস, বিগত সময় = 0 এমএস।

মৃত্যুদণ্ড কার্যকর করার পরিকল্পনাগুলি:

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন

এক্ষেত্রে কেন ইনলাইন বৈকল্পিকটি বহু-বিবৃতি বৈকল্পিকের চেয়ে এত ধীরে ধীরে?

@ অ্যারোনবার্ট্রেন্ডের মন্তব্যের জবাবে, আমি dbo.InlineIsPalindromeসিটিই দ্বারা প্রদত্ত সারিগুলি ইনপুট শব্দের দৈর্ঘ্যের সাথে মেলে সীমাবদ্ধ করার জন্য ফাংশনটি সংশোধন করেছি :

CREATE FUNCTION dbo.InlineIsPalindrome
(
    @Word NVARCHAR(500)
)
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN (
    WITH Nums AS
    (
      SELECT
        N = number
      FROM
        dbo.Numbers
      WHERE 
        number <= LEN(@Word)
    )
    SELECT
      IsPalindrome =
        CASE
          WHEN EXISTS
          (
            SELECT N
            FROM Nums
            WHERE N <= L / 2
              AND SUBSTRING(S, N, 1) <> SUBSTRING(S, 1 + L - N, 1)
          )
          THEN 0
          ELSE 1
        END
    FROM
      (SELECT LTRIM(RTRIM(@Word)), LEN(@Word)) AS v (S, L)
);

@ মার্টিনস্মিথের পরামর্শ অনুসারে, আমি dbo.Numbersটেবিলে একটি প্রাথমিক কী এবং ক্লাস্টারড ইনডেক্স যুক্ত করেছি , যা অবশ্যই উত্পাদনের পরিবেশে যা প্রত্যাশা করবে তার কাছাকাছি সাহায্য করবে এবং এর নিকটবর্তী হবে।

উপরের পরীক্ষাগুলি এখন আবার চালানো নীচের পরিসংখ্যানগুলির ফলাফল:

CROSS APPLY dbo.IsPalindrome(w.Word) p:

(17424 সারি (গুলি) প্রভাবিত)
সারণী '# B1104853'। স্ক্যানের গণনা 17420, লজিকাল 17424, শারীরিক 0 0, পঠিত-এগিয়ে 0, লব লজিকাল 0, লব শারীরিক 0, লব পঠন-এগিয়ে 0 টি
সারণী 'ওয়ার্কটেবল'। স্ক্যান কাউন্ট 0, লজিকাল রিড 0, ফিজিকাল রিড 0, রিড-ফরোডড রিড 0, লব লজিকাল রিড 0, লব ফিজিকাল রিড 0, লব রিড-
ফরোয়ার্ড 0 টেবিল '# ওয়ার্ডস'। স্ক্যান কাউন্ট 1, লজিকাল রিডিজ 90, ফিজিকাল রিড 0, রিড-ফরোডড রিড 0, লব লজিকাল রিড 0, লব ফিজিকাল 0, লব রিড-ফরোয়ার্ড 0

এসকিউএল সার্ভার এক্সিকিউশন টাইমস:
সিপিইউ সময় = 1763 এমএস, অতিবাহিত সময় = 2192 এমএস।

dbo.FunctionIsPalindrome(w.Word):

(17424 সারি প্রভাবিত)
সারণী 'ওয়ার্কটেবল'। স্ক্যান কাউন্ট 0, লজিকাল রিড 0, ফিজিকাল রিড 0, রিড-ফরোডড রিড 0, লব লজিকাল রিড 0, লব ফিজিকাল রিড 0, লব রিড-
ফরোয়ার্ড 0 টেবিল '# ওয়ার্ডস'। স্ক্যান কাউন্ট 1, লজিকাল রিডিজ 90, ফিজিকাল রিড 0, রিড-ফরোডড রিড 0, লব লজিকাল রিড 0, লব ফিজিকাল 0, লব রিড-ফরোয়ার্ড 0

এসকিউএল সার্ভার এক্সিকিউশন টাইমস:
সিপিইউ সময় = 328 এমএস, অতিবাহিত সময় = 424 এমএস।

CROSS APPLY dbo.InlineIsPalindrome(w.Word) p:

(17424 সারি প্রভাবিত)
সারণী 'নম্বর'। স্ক্যান কাউন্ট 1, লজিকাল রিডিং 237100, ফিজিকাল রিড 0, রিড-ফরোয়ার্ড 0 পড়ে, লব লজিকাল রিড 0, লব ফিজিকাল রিড 0, লব রিড-
ফরোয়ার্ড 0 টেবিল 'ওয়ার্কটেবল'। স্ক্যান কাউন্ট 0, লজিকাল রিড 0, ফিজিকাল রিড 0, রিড-ফরোডড রিড 0, লব লজিকাল রিড 0, লব ফিজিকাল রিড 0, লব রিড-
ফরোয়ার্ড 0 টেবিল '# ওয়ার্ডস'। স্ক্যান কাউন্ট 1, লজিকাল রিডিজ 90, ফিজিকাল রিড 0, রিড-ফরোডড রিড 0, লব লজিকাল রিড 0, লব ফিজিকাল 0, লব রিড-ফরোয়ার্ড 0

এসকিউএল সার্ভার এক্সিকিউশন টাইমস:
সিপিইউ সময় = 17737 এমএস, অতিবাহিত সময় = 17946 এমএস।

আমি এটি এসকিউএল সার্ভার 2012 এসপি 3, v11.0.6020, বিকাশকারী সংস্করণে পরীক্ষা করছি।

এখানে প্রাথমিক কী এবং ক্লাস্টারড সূচক সহ আমার নম্বর সারণীর সংজ্ঞা দেওয়া আছে:

CREATE TABLE dbo.Numbers
(
    Number INT NOT NULL 
        CONSTRAINT PK_Numbers
        PRIMARY KEY CLUSTERED
);

;WITH n AS
(
    SELECT v.n 
    FROM (
        VALUES (1) 
            ,(2) 
            ,(3) 
            ,(4) 
            ,(5) 
            ,(6) 
            ,(7) 
            ,(8) 
            ,(9) 
            ,(10)
        ) v(n)
)
INSERT INTO dbo.Numbers(Number)
SELECT ROW_NUMBER() OVER (ORDER BY n1.n)
FROM n n1
    , n n2
    , n n3
    , n n4
    , n n5
    , n n6;

মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
পল হোয়াইট পুনর্নির্মাণ মনিকা

উত্তর:


12

আপনার নম্বর টেবিলটি একটি গাদা এবং সম্ভাব্যভাবে প্রতিবার সম্পূর্ণ স্ক্যান করা হচ্ছে।

একটি ক্লাস্টার্ড প্রাথমিক কী যুক্ত করুন Numberএবং forceseekপছন্দসই সন্ধান পেতে একটি ইঙ্গিত দিয়ে নিম্নলিখিতটি চেষ্টা করুন ।

যতদূর আমি এই ইঙ্গিতটি এসকিউএল সার্ভারের হিসাবে প্রয়োজন ঠিক এটি অনুমান করতে পারি যে টেবিলের 27% প্রাকটিকের সাথে মিলবে (30% এর জন্য <=এবং কমিয়ে ২ 27% হয়ে যাবে <>)। এবং সেইজন্য যে এটি মেলে তার সন্ধানের আগে কেবল 3-4 টি সারি পড়তে হবে এবং এটি সেমি যোগটি থেকে প্রস্থান করতে পারে। সুতরাং স্ক্যান অপশনটি খুব সস্তাভাবে কাস্ট করা হয়। তবে বাস্তবে যদি কোনও প্যালিনড্রোম উপস্থিত থাকে তবে এটি পুরো টেবিলটি পড়তে হবে তাই এটি কোনও ভাল পরিকল্পনা নয়।

CREATE FUNCTION dbo.InlineIsPalindrome
(
    @Word NVARCHAR(500)
)
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN (
    WITH Nums AS
    (
      SELECT
        N = number
      FROM
        dbo.Numbers WITH(FORCESEEK)
    )
    SELECT
      IsPalindrome =
        CASE
          WHEN EXISTS
          (
            SELECT N
            FROM Nums
            WHERE N <= L / 2
              AND SUBSTRING(S, N, 1) <> SUBSTRING(S, 1 + L - N, 1)
          )
          THEN 0
          ELSE 1
        END
    FROM
      (SELECT LTRIM(RTRIM(@Word)), LEN(@Word)) AS v (S, L)
);
GO

পরিবর্তিত স্থানগুলির সাথে এটি আমার জন্য উড়ে যায় (228 মিমি লাগে)

এখানে চিত্র বর্ণনা লিখুন

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