সন্ধান করুন এবং আপনি পার্টিশনযুক্ত টেবিলগুলিতে ... স্ক্যান করতে পারবেন


22

আমি এই নিবন্ধগুলি ইটজিক বেন-গানের পিসিমেগে পড়েছি :

সেকেন্ড এবং আপনি স্ক্যান পার্ট আইটি ভাগ করবেন: যখন অপ্টিমাইজারটি অপ্টিমাইজ করবেন না
এবং আপনি দ্বিতীয় খণ্ড স্ক্যান করতে পারবেন: আরোহণ কীগুলি

আমি বর্তমানে আমাদের সমস্ত বিভাজনযুক্ত টেবিলের সাথে একটি "গ্রুপযুক্ত সর্বোচ্চ" সমস্যাটি নিয়েছি। আমরা ইটজিক বেন-গান সর্বোচ্চ (আইডি) পাওয়ার জন্য সরবরাহিত কৌশলটি ব্যবহার করি তবে কখনও কখনও এটি চালানো হয় না:

DECLARE @MaxIDPartitionTable BIGINT
SELECT  @MaxIDPartitionTable = ISNULL(MAX(IDPartitionedTable), 0)
FROM    ( SELECT    *
          FROM      ( SELECT    partition_number PartitionNumber
                      FROM      sys.partitions
                      WHERE     object_id = OBJECT_ID('fct.MyTable')
                                AND index_id = 1
                    ) T1
                    CROSS APPLY ( SELECT    ISNULL(MAX(UpdatedID), 0) AS IDPartitionedTable
                                  FROM      fct.MyTable s
                                  WHERE     $PARTITION.PF_MyTable(s.PCTimeStamp) = PartitionNumber
                                            AND UpdatedID <= @IDColumnThresholdValue
                                ) AS o
        ) AS T2;
SELECT @MaxIDPartitionTable 

আমি এই পরিকল্পনা পেয়েছি

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

তবে 45 মিনিটের পরে, রিডগুলি দেখুন look

reads          writes   physical_reads
12,949,127        2       12,992,610

যে আমি এড়িয়ে যেতে sp_whoisactive

সাধারণত এটি বেশ দ্রুত চলে তবে আজ নয়।

সম্পাদনা করুন: পার্টিশন সহ টেবিল কাঠামো:

CREATE PARTITION FUNCTION [MonthlySmallDateTime](SmallDateTime) AS RANGE RIGHT FOR VALUES (N'2000-01-01T00:00:00.000', N'2000-02-01T00:00:00.000' /* and many more */)
go
CREATE PARTITION SCHEME PS_FctContractualAvailability AS PARTITION [MonthlySmallDateTime] TO ([Standard], [Standard])
GO
CREATE TABLE fct.MyTable(
    MyTableID BIGINT IDENTITY(1,1),
    [DT1TurbineID] INT NOT NULL,
    [PCTimeStamp] SMALLDATETIME NOT NULL,
    Filler CHAR(100) NOT NULL DEFAULT 'N/A',
    UpdatedID BIGINT NULL,
    UpdatedDate DATETIME NULL
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED 
(
    [DT1TurbineID] ASC,
    [PCTimeStamp] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION = ROW) ON [PS_FctContractualAvailability]([PCTimeStamp])
) ON [PS_FctContractualAvailability]([PCTimeStamp])

GO

CREATE UNIQUE NONCLUSTERED INDEX [IX_UpdatedID_PCTimeStamp] ON [fct].MyTable
(
    [UpdatedID] ASC,
    [PCTimeStamp] ASC
)
INCLUDE (   [UpdatedDate]) 
WHERE ([UpdatedID] IS NOT NULL)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, DATA_COMPRESSION = ROW) ON [PS_FctContractualAvailability]([PCTimeStamp])
GO

উত্তর:


28

মূল বিষয়টি হ'ল সূচীকরণ অনুসন্ধানটি শীর্ষ অপারেটর দ্বারা অনুসরণ করা হয় না। এটি এমন একটি অপ্টিমাইজেশন যা সাধারণত যখন সূচিত হয় তখন MIN\MAXসামগ্রিকের জন্য সঠিক ক্রমে সারিগুলি দেয় তখনই এটি চালু হয় ।

এই অপ্টিমাইজেশানটি সত্যতাটিকে কাজে লাগায় যে নূন্যতম / সর্বাধিক সারিটি আরোহী বা উতরান ক্রমের প্রথম। এটিও হতে পারে যে অপটিমাইজার বিভাজনযুক্ত টেবিলগুলিতে এই অপ্টিমাইজেশনটি প্রয়োগ করতে পারে না; আমি ভুলে যাই.

যাইহোক, মুল বক্তব্যটি হ'ল এই রূপান্তরটি ছাড়াই, এক্সিকিউশন প্ল্যান্ট প্রতিটি পার্ট প্রক্রিয়াকরণ শেষ করে যা S.UpdatedID <= @IDColumnThresholdValueপার্টিশন প্রতি কাঙ্ক্ষিত এক সারির চেয়ে পার্টিশন অনুযায়ী যোগ্য হয় ।

আপনি প্রশ্নের মধ্যে সারণী, সূচী বা পার্টিশন সংজ্ঞা সরবরাহ করেন নি তাই আমি আরও নির্দিষ্ট করে বলতে পারি না। আপনার সূচিটি এমন রূপান্তরকে সমর্থন করবে কিনা তা পরীক্ষা করা উচিত। কম বা কম সমতুল্য, আপনি এ MAXহিসাবে প্রকাশ করতে পারে TOP (1) ... ORDER BY UpdatedID DESC

যদি এর ফলাফলটি একটি সারণিতে হয় ( শীর্ষস্থানীয় বাছাই সহ ), আপনি জানেন যে আপনার সূচকটি সহায়ক নয়। উদাহরণ স্বরূপ:

SELECT
    @MaxIDPartitionTable = ISNULL(MAX(T2.IDPartitionedTable), 0)
FROM    
( 
    SELECT
        O.IDPartitionedTable
    FROM      
    ( 
        SELECT
            P.partition_number AS PartitionNumber
        FROM sys.partitions AS P
        WHERE 
            P.[object_id] = OBJECT_ID(N'fct.MyTable', N'U')
            AND P.index_id = 1
    ) AS T1
    CROSS APPLY 
    (    
        SELECT TOP (1) 
            S.UpdatedID AS IDPartitionedTable
        FROM fct.MyTable AS S
        WHERE
            $PARTITION.PF_MyTable(S.PCTimeStamp) = T1.PartitionNumber
            AND S.UpdatedID <= @IDColumnThresholdValue
        ORDER BY
            S.UpdatedID DESC
    ) AS O
) AS T2;

এই উত্পাদনের পরিকল্পনার আকারটি হ'ল:

পছন্দসই পরিকল্পনার আকার

সূচী অনুসন্ধানের নীচে শীর্ষগুলি লক্ষ্য করুন। এটি প্রক্রিয়াটি পার্টিশন প্রতি এক সারিতে সীমাবদ্ধ করে।

অথবা, পার্টিশন নম্বর ধরে রাখতে একটি অস্থায়ী টেবিল ব্যবহার করে:

CREATE TABLE #Partitions
(
    partition_number integer PRIMARY KEY CLUSTERED
);

INSERT #Partitions
    (partition_number)
SELECT
    P.partition_number AS PartitionNumber
FROM sys.partitions AS P
WHERE 
    P.[object_id] = OBJECT_ID(N'fct.MyTable', N'U')
    AND P.index_id = 1;

SELECT
    @MaxIDPartitionTable = ISNULL(MAX(T2.UpdatedID), 0)
FROM #Partitions AS P
CROSS APPLY 
(
    SELECT TOP (1) 
        S.UpdatedID
    FROM fct.MyTable AS S
    WHERE
        $PARTITION.PF_MyTable(S.PCTimeStamp) = P.partition_number
        AND S.UpdatedID <= @IDColumnThresholdValue
    ORDER BY
        S.UpdatedID DESC
) AS T2;

DROP TABLE #Partitions;

পার্শ্ব নোট: আপনার ক্যোয়ারীতে একটি সিস্টেম টেবিল অ্যাক্সেস সমান্তরালতা প্রতিরোধ করে। যদি এটি গুরুত্বপূর্ণ হয় তবে অস্থায়ী টেবিলের মধ্যে পার্টিশন নম্বরগুলি বাস্তবায়নের কথা বিবেচনা করুন, তারপরে APPLYসেগুলি থেকে। সমান্তরালতা এই প্যাটার্নে সাধারণত সঠিক নয় (সঠিক ইনডেক্সিং সহ) তবে এটি উল্লেখ না করা আমার পক্ষে পরিতোষ হবে।

পার্শ্ব নোট 2: সেখানে একটি সক্রিয় সংযোগ আইটেমMIN\MAX সমষ্টিগুলির জন্য বিল্ট-ইন সমর্থন এবং পার্টিশনযুক্ত অবজেক্টগুলিতে শীর্ষের জন্য অনুরোধ করছে ।

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