ROW_NUMBER () পার্টিশন ব্যতীত এখনও সেগমেন্টের পুনরুক্তি উত্পাদন করে


11

আমি র‌্যাঙ্কিং এবং সামগ্রিক উইন্ডো ফাংশনগুলিতে বিশেষত সেগমেন্ট এবং সিকোয়েন্স প্রজেক্ট পুনরুক্তি সম্পর্কিত আমার একটি আগত ব্লগ পোস্টে লিখছি। যেভাবে আমি এটি বুঝতে পারি সেগমেন্টটি একটি স্রোতে সারিগুলি সনাক্ত করে যা একটি গোষ্ঠীর শেষ / প্রারম্ভিক গঠন করে, সুতরাং নিম্নলিখিত প্রশ্নটি:

SELECT ROW_NUMBER() OVER (PARTITION BY someGroup ORDER BY someOrder)

কখন একটি সারি পূর্ববর্তী সারির ব্যতীত অন্য কোনও গ্রুপের অন্তর্ভুক্ত তা জানাতে সেগমেন্ট ব্যবহার করবে। সিকোয়েন্স প্রজেক্ট পুনরুক্তি করাংশটি সেগমেন্ট পুনরুক্তরের আউটপুটের উপর ভিত্তি করে প্রকৃত সারি সংখ্যা গণনা করে।

কিন্তু নিম্নলিখিত কোয়েরিতে, সেই যুক্তিটি ব্যবহার করে, কোনও বিভাগকে অন্তর্ভুক্ত করা উচিত নয়, কারণ কোনও বিভাজন প্রকাশ নেই।

SELECT ROW_NUMBER() OVER (ORDER BY someGroup, someOrder)

যাইহোক, যখন আমি এই অনুমানটি চেষ্টা করি তখন এই উভয় প্রশ্নেরই একটি সেগমেন্ট অপারেটর ব্যবহার করা হয়। পার্থক্যটি হ'ল দ্বিতীয় ক্যোয়ারিতে GroupByসেগমেন্টে কোনও প্রয়োজন নেই । এটি কি প্রথম অংশে কোনও বিভাগের প্রয়োজনকে দূর করে না?

উদাহরণ

CREATE TABLE dbo.someTable (
    someGroup   int NOT NULL,
    someOrder   int NOT NULL,
    someValue   numeric(8, 2) NOT NULL,
    PRIMARY KEY CLUSTERED (someGroup, someOrder)
);

--- Query 1:
SELECT ROW_NUMBER() OVER (PARTITION BY someGroup ORDER BY someOrder)
FROM dbo.someTable;

--- Query 2:
SELECT ROW_NUMBER() OVER (ORDER BY someGroup, someOrder)
FROM dbo.someTable;

1
যদিও কোনও বিভাজন প্রকাশ নেই, আমার ধারণা আপনি এখনও প্রযুক্তিগতভাবে ফলাফলকে বিভাজনে বিভক্ত করছেন, তবে এক্ষেত্রে কেবল একটিই?
মার্ক সিনিংসন

কিউপি খালি দেখায় <GroupBy />তাই বিভাগটি সত্যিকার অর্থে কিছুই করে না, প্রায়শই সিকোয়েন্স প্রজেক্ট অপারেটরে সেগমেন্ট কলামটি আউটপুট করে। সেগমেন্ট অপারেটর থাকার কারণ হতে পারে যে সিকোয়েন্স প্রজেক্ট অপারেটরের কাজটি করার জন্য সেই মানটি প্রয়োজন।
মিকেল এরিকসন

এটি আমার তত্ত্বও। তবে অপ্টিমাইজার সাধারণত এই ধরণের অপ্রয়োজনীয় অপারেটরদের থেকে দূরে সরে যায়, ...
ড্যানিয়েল হুটমাচার

উত্তর:


12

আমি 6 বছরের পুরানো ব্লগ পোস্টটি একই আচরণের উল্লেখ করে পেয়েছি।

দেখে মনে হচ্ছে ROW_NUMBER()সর্বদা সেগমেন্ট অপারেটর অন্তর্ভুক্ত রয়েছে, PARTITION BYব্যবহৃত হয়েছে কিনা । যদি আমার অনুমান করতে হয় তবে আমি এটি বলব কারণ এটি ইঞ্জিনে কোয়েরি পরিকল্পনা তৈরি করা সহজ করে তোলে।

যদি বেশিরভাগ ক্ষেত্রে বিভাগটির প্রয়োজন হয় এবং যে ক্ষেত্রে এটির প্রয়োজন হয় না মূলত এটি শূন্য-ব্যয়বহুল অপারেশন হয়, উইন্ডোটিং ফাংশনটি ব্যবহৃত হয় যখন এটি সর্বদা পরিকল্পনার মধ্যে অন্তর্ভুক্ত করা অনেক সহজ।


11

এক্সপ্লোরেশন পরিকল্পনার showplan.xsd অনুসারে, উপস্থিতি বা বৈশিষ্ট্য GroupByছাড়াই উপস্থিত হয় যা মূলত [১.১] মূল উপাদানকে বাধ্যতামূলক করে তোলে, প্রয়োজনীয় বিষয়বস্তু নয়। সন্তান উপাদান ধরনের ( ) আছে 0 এবং সীমাবদ্ধ [0 .. *], এটি তৈরি ঐচ্ছিক , অত অনুমতি খালি উপাদান। আপনি যদি ম্যানুয়ালি এই অপসারণ এবং পরিকল্পনাটি জোর করার চেষ্টা করেন তবে আপনি প্রত্যাশিত ত্রুটিটি পান:minOccursmaxOccursColumnReferenceColumnReferenceTypeminOccursmaxOccursGroupBy

Msg 6965, Level 16, State 1, Line 29
XML Validation: Invalid content. Expected element(s): '{http://schemas.microsoft.com/sqlserver/2004/07/showplan}GroupBy','{http://schemas.microsoft.com/sqlserver/2004/07/showplan}DefinedValues','{http://schemas.microsoft.com/sqlserver/2004/07/showplan}InternalInfo'. Found: element '{http://schemas.microsoft.com/sqlserver/2004/07/showplan}SegmentColumn' instead. Location: /*:ShowPlanXML[1]/*:BatchSequence[1]/*:Batch[1]/*:Statements[1]/*:StmtSimple[1]/*:QueryPlan[1]/*:RelOp[1]/*:SequenceProject[1]/*:RelOp[1]/*:Segment[1]/*:SegmentColumn[1].

আকর্ষণীয়ভাবে আমি দেখতে পেয়েছি যে আপনি জোর করে যা করার মতো একটি বৈধ পরিকল্পনা পেতে আপনি নিজেই সেগমেন্ট অপারেটরটি সরিয়ে ফেলতে পারেন:

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

তবে আপনি যখন সেই পরিকল্পনাটি চালাবেন (ব্যবহার করে OPTION ( USE PLAN ... )) সেগমেন্ট অপারেটরটি যাদুকরীভাবে উপস্থিত হবে। কেবলমাত্র অপ্টিমাইজারটি দেখাতে যায় এক্সএমএল পরিকল্পনাগুলিকে মোটামুটি গাইড হিসাবে গ্রহণ করে।

আমার পরীক্ষার ছদ্মবেশ:

USE tempdb
GO
SET NOCOUNT ON
GO
IF OBJECT_ID('dbo.someTable') IS NOT NULL DROP TABLE dbo.someTable
GO
CREATE TABLE dbo.someTable (
    someGroup   int NOT NULL,
    someOrder   int NOT NULL,
    someValue   numeric(8, 2) NOT NULL,
    PRIMARY KEY CLUSTERED (someGroup, someOrder)
);
GO

-- Generate some dummy data
;WITH cte AS (
SELECT TOP 1000 ROW_NUMBER() OVER ( ORDER BY ( SELECT 1 ) ) rn
FROM master.sys.columns c1
    CROSS JOIN master.sys.columns c2
    CROSS JOIN master.sys.columns c3
)
INSERT INTO dbo.someTable ( someGroup, someOrder, someValue )
SELECT rn % 333, rn % 444, rn % 55
FROM cte
GO


-- Try and force the plan
SELECT ROW_NUMBER() OVER (ORDER BY someGroup, someOrder)
FROM dbo.someTable
OPTION ( USE PLAN N'<?xml version="1.0" encoding="utf-16"?>
<ShowPlanXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.2" Build="12.0.2000.8" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="1" StatementEstRows="1000" StatementId="1" StatementOptmLevel="TRIVIAL" CardinalityEstimationModelVersion="120" StatementSubTreeCost="0.00596348" StatementText="SELECT ROW_NUMBER() OVER (ORDER BY someGroup, someOrder)&#xD;&#xA;FROM dbo.someTable" StatementType="SELECT" QueryHash="0x193176312402B8E7" QueryPlanHash="0x77F1D72C455025A4" RetrievedFromCache="true">
          <StatementSetOptions ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="true" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="true" />
          <QueryPlan DegreeOfParallelism="1" CachedPlanSize="16" CompileTime="0" CompileCPU="0" CompileMemory="88">
            <OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="131072" EstimatedPagesCached="65536" EstimatedAvailableDegreeOfParallelism="4" />
            <RelOp AvgRowSize="15" EstimateCPU="8E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1000" LogicalOp="Compute Scalar" NodeId="0" Parallel="false" PhysicalOp="Sequence Project" EstimatedTotalSubtreeCost="0.00596348">
              <OutputList>
                <ColumnReference Column="Expr1002" />
              </OutputList>
              <SequenceProject>
                <DefinedValues>
                  <DefinedValue>
                    <ColumnReference Column="Expr1002" />
                    <ScalarOperator ScalarString="row_number">
                      <Sequence FunctionName="row_number" />
                    </ScalarOperator>
                  </DefinedValue>
                </DefinedValues>

                <!-- Segment operator completely removed from plan -->
                <!--<RelOp AvgRowSize="15" EstimateCPU="2E-05" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1000" LogicalOp="Segment" NodeId="1" Parallel="false" PhysicalOp="Segment" EstimatedTotalSubtreeCost="0.00588348">
                  <OutputList>
                    <ColumnReference Database="[tempdb]" Schema="[dbo]" Table="[someTable]" Column="someGroup" />
                    <ColumnReference Database="[tempdb]" Schema="[dbo]" Table="[someTable]" Column="someOrder" />
                    <ColumnReference Column="Segment1003" />
                  </OutputList>
                  <Segment>
                    <GroupBy />
                    <SegmentColumn>
                      <ColumnReference Column="Segment1003" />
                    </SegmentColumn>-->


                    <RelOp AvgRowSize="15" EstimateCPU="0.001257" EstimateIO="0.00460648" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1000" LogicalOp="Clustered Index Scan" NodeId="0" Parallel="false" PhysicalOp="Clustered Index Scan" EstimatedTotalSubtreeCost="0.00586348" TableCardinality="1000">
                      <OutputList>
                        <ColumnReference Database="[tempdb]" Schema="[dbo]" Table="[someTable]" Column="someGroup" />
                        <ColumnReference Database="[tempdb]" Schema="[dbo]" Table="[someTable]" Column="someOrder" />
                      </OutputList>
                      <IndexScan Ordered="true" ScanDirection="FORWARD" ForcedIndex="false" ForceSeek="false" ForceScan="false" NoExpandHint="false" Storage="RowStore">
                        <DefinedValues>
                          <DefinedValue>
                            <ColumnReference Database="[tempdb]" Schema="[dbo]" Table="[someTable]" Column="someGroup" />
                          </DefinedValue>
                          <DefinedValue>
                            <ColumnReference Database="[tempdb]" Schema="[dbo]" Table="[someTable]" Column="someOrder" />
                          </DefinedValue>
                        </DefinedValues>
                        <Object Database="[tempdb]" Schema="[dbo]" Table="[someTable]" Index="[PK__someTabl__7CD03C8950FF62C1]" IndexKind="Clustered" Storage="RowStore" />
                      </IndexScan>
                    </RelOp>

                <!--</Segment>
                </RelOp>-->
              </SequenceProject>
            </RelOp>

          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>' )

এক্সএমএল পরিকল্পনাটি পরীক্ষার ছদ্মবেশ থেকে কাটা এবং সেগমেন্টটি বিয়োগ করার জন্য এটি একটি এস। এসপ্ল্যাপ্লান হিসাবে সংরক্ষণ করুন।

পিএস আমি নিজেই এসকিউএল পরিকল্পনাগুলির চারপাশে কাটা খুব বেশি সময় ব্যয় করব না যেন আপনি আমাকে জানেন আপনি জানতেন আমি এটিকে সময় খাওয়া ব্যস্ত কাজ এবং এমন কিছু হিসাবে বিবেচনা করব যা আমি কখনই করব না। ওহ হ্যাং !? :)


আপনার হাতে অনেক বেশি সময় আছে ... দুর্দান্ত কাজ!
মার্ক সিনিংসন

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