Dự toán tính toán chi phí khai thác


7

Ở mọi nơi tôi đã đọc nói rằng Chi phí khai thác ước tính là tổng của Chi phí CPU ước tính và Chi phí I / O ước tính. Tuy nhiên, trong nhiều nhà khai thác tôi thấy, đây không phải là trường hợp. Đây là một ví dụ:

SELECT Column2
INTO   Object1
FROM   Object2
WHERE  Column3 >= Variable2
       AND Column3 <= Variable1
       AND ( Column4 = Variable5
              OR Variable5 = ? ) 

nhập mô tả hình ảnh ở đây

Ước tính = "0,01" Ước tínhCPU = "0,000246492"

Tổng: 0,010246492

Tuy nhiên, SSMS hiển thị 0,073823 này dưới dạng Chi phí khai thác ước tính. Tôi hoàn toàn mất khả năng tính toán như thế nào. Dưới đây là kế hoạch thực hiện xml (ẩn danh). Nút Node 0 là nút trong câu hỏi.

<?xml version="1.0" encoding="utf-16"?>
<ShowPlanXML xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan" Version="1.2" Build="11.0.6537.0">
    <BatchSequence>
        <Batch>
            <Statements>
                <StmtSimple StatementText="&#x9;SELECT Column2 INTO Object1 &#xD;&#xA;&#x9;FROM Object2&#xD;&#xA;&#x9;WHERE Column3&gt;=Variable2 AND Column3&lt;=Variable1 &#xD;&#xA;&#x9;AND (Column4=Variable5 OR Variable5=?)&#xD;&#xA;&#xD;&#xA;" StatementId="1" StatementCompId="7" StatementType="SELECT INTO" RetrievedFromCache="true" StatementSubTreeCost="0.405134" StatementEstRows="246.492" StatementOptmLevel="FULL" QueryHash="0x180DF38DFFFEAFA2" QueryPlanHash="0x45A4295471B90968" StatementOptmEarlyAbortReason="GoodEnoughPlanFound">
                    <StatementSetOptions QUOTED_IDENTIFIER="true" ARITHABORT="false" CONCAT_NULL_YIELDS_NULL="true" ANSI_NULLS="true" ANSI_PADDING="true" ANSI_WARNINGS="true" NUMERIC_ROUNDABORT="false" />
                    <QueryPlan CachedPlanSize="48" CompileTime="23" CompileCPU="6" CompileMemory="360">
                        <MemoryGrantInfo SerialRequiredMemory="0" SerialDesiredMemory="0" />
                        <OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="157286" EstimatedPagesCached="314572" EstimatedAvailableDegreeOfParallelism="16" />
                        <RelOp NodeId="0" PhysicalOp="Table Insert" LogicalOp="Insert" EstimateRows="246.492" EstimateIO="0.01" EstimateCPU="0.000246492" AvgRowSize="9" EstimatedTotalSubtreeCost="0.405134" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
                            <OutputList />
                            <Update DMLRequestSort="0">
                                <Object Table="Object1" />
                                <SetPredicate>
                                    <ScalarOperator ScalarString="ScalarString1">
                                        <ScalarExpressionList>
                                            <ScalarOperator>
                                                <MultipleAssign>
                                                    <Assign>
                                                        <ColumnReference Table="Object1" Column="Column2" />
                                                        <ScalarOperator>
                                                            <Identifier>
                                                                <ColumnReference Database="Database1" Schema="Schema1" Table="Object2" Column="Column2" />
                                                            </Identifier>
                                                        </ScalarOperator>
                                                    </Assign>
                                                </MultipleAssign>
                                            </ScalarOperator>
                                        </ScalarExpressionList>
                                    </ScalarOperator>
                                </SetPredicate>
                                <RelOp NodeId="1" PhysicalOp="Index Seek" LogicalOp="Index Seek" EstimateRows="246.492" EstimateIO="0.22831" EstimateCPU="0.103001" AvgRowSize="15" EstimatedTotalSubtreeCost="0.331311" TableCardinality="1.03883e+006" Parallel="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row">
                                    <OutputList>
                                        <ColumnReference Database="Database1" Schema="Schema1" Table="Object2" Column="Column2" />
                                    </OutputList>
                                    <IndexScan Ordered="1" ScanDirection="FORWARD" ForcedIndex="0" ForceSeek="0" ForceScan="0" NoExpandHint="0" Storage="RowStore">
                                        <DefinedValues>
                                            <DefinedValue>
                                                <ColumnReference Database="Database1" Schema="Schema1" Table="Object2" Column="Column2" />
                                            </DefinedValue>
                                        </DefinedValues>
                                        <Object Database="Database1" Schema="Schema1" Table="Object2" Index="Index1" IndexKind="NonClustered" />
                                        <SeekPredicates>
                                            <SeekPredicateNew>
                                                <SeekKeys>
                                                    <StartRange ScanType="GE">
                                                        <RangeColumns>
                                                            <ColumnReference Database="Database1" Schema="Schema1" Table="Object2" Column="Column3" />
                                                        </RangeColumns>
                                                        <RangeExpressions>
                                                            <ScalarOperator ScalarString="ScalarString2">
                                                                <Identifier>
                                                                    <ColumnReference Column="Column7" />
                                                                </Identifier>
                                                            </ScalarOperator>
                                                        </RangeExpressions>
                                                    </StartRange>
                                                    <EndRange ScanType="LE">
                                                        <RangeColumns>
                                                            <ColumnReference Database="Database1" Schema="Schema1" Table="Object2" Column="Column3" />
                                                        </RangeColumns>
                                                        <RangeExpressions>
                                                            <ScalarOperator ScalarString="ScalarString3">
                                                                <Identifier>
                                                                    <ColumnReference Column="Column8" />
                                                                </Identifier>
                                                            </ScalarOperator>
                                                        </RangeExpressions>
                                                    </EndRange>
                                                </SeekKeys>
                                            </SeekPredicateNew>
                                        </SeekPredicates>
                                        <Predicate>
                                            <ScalarOperator ScalarString="ScalarString4">
                                                <Logical Operation="OR">
                                                    <ScalarOperator>
                                                        <Compare CompareOp="EQ">
                                                            <ScalarOperator>
                                                                <Identifier>
                                                                    <ColumnReference Database="Database1" Schema="Schema1" Table="Object2" Column="Column4" />
                                                                </Identifier>
                                                            </ScalarOperator>
                                                            <ScalarOperator>
                                                                <Identifier>
                                                                    <ColumnReference Column="Column9" />
                                                                </Identifier>
                                                            </ScalarOperator>
                                                        </Compare>
                                                    </ScalarOperator>
                                                    <ScalarOperator>
                                                        <Identifier>
                                                            <ColumnReference Column="Column10">
                                                                <ScalarOperator>
                                                                    <Compare CompareOp="EQ">
                                                                        <ScalarOperator>
                                                                            <Identifier>
                                                                                <ColumnReference Column="Column9" />
                                                                            </Identifier>
                                                                        </ScalarOperator>
                                                                        <ScalarOperator>
                                                                            <Const ConstValue="Value4" />
                                                                        </ScalarOperator>
                                                                    </Compare>
                                                                </ScalarOperator>
                                                            </ColumnReference>
                                                        </Identifier>
                                                    </ScalarOperator>
                                                </Logical>
                                            </ScalarOperator>
                                        </Predicate>
                                    </IndexScan>
                                </RelOp>
                            </Update>
                        </RelOp>
                        <ParameterList>
                            <ColumnReference Column="Column9" ParameterCompiledValue="Value1" />
                        </ParameterList>
                    </QueryPlan>
                </StmtSimple>
            </Statements>
        </Batch>
    </BatchSequence>
</ShowPlanXML>

EDIT: Nhận ra tôi đã không đăng một câu hỏi được xây dựng tốt. Đây là câu hỏi:

Dựa vào kế hoạch ví dụ, SSMS và Plan Explorer đã sử dụng công thức hoặc tính toán nào để đi đến Chi phí khai thác ước tính là 0,073823 cho Nút 0?


2
Trình thám hiểm kế hoạch SQL Sentry hiển thị các kết quả khác nhau i.stack.imgur.com/uEo3m.png - có vẻ như họ phải điều chỉnh các giá trị để làm cho chúng phù hợp.
Martin Smith

Phải, tôi sử dụng Plan Explorer cũng như Martin và thấy điều đó. Vì vậy, tôi rất tò mò, làm thế nào họ tính toán điều đó? Có vẻ như chi phí I / O đã được điều chỉnh trong Plan Explorer. Sau đó, thám hiểm kế hoạch hiển thị cùng một Chi phí khai thác ước tính chính xác. Plan Explorer đã thực hiện thay đổi chi phí I / O dẫn đến Chi phí khai thác phù hợp như thế nào?
SpaceGhost440

Câu trả lời:


3

Cách duy nhất để trả lời đúng câu hỏi đó là kích hoạt trình gỡ lỗi và xem những lựa chọn nào được đưa ra bởi trình tối ưu hóa trên đường đi. Các chi phí không chỉ có IO và CPU. Có các chi phí bổ sung liên quan đến một toán tử nhất định được phản ánh trong tổng chi phí, nhưng không được phản ánh trong các ước tính chi phí IO và CPU. Bạn có thể đọc thêm về một số chi phí bổ sung trong bài viết xuất sắc này của Paul White . 🕗

Tôi không có câu trả lời chính xác cho câu hỏi của bạn (Tôi không nghi ngờ gì, Paul sẽ). Tuy nhiên, tôi sẵn sàng đoán. Những gì bạn đang thấy được thêm vào chi phí cho hoạt động được xác định bởi trình tối ưu hóa ở trên và ngoài những gì nó đang hiển thị là chi phí cho IO và CPU được xác định bởi các hàng ước tính, v.v. Tôi tin rằng đó là một phép tính dựa trên những gì sẽ cần thiết về mặt IO để tạo bảng và lưu trữ dữ liệu trị giá 246.492 hàng * 9b trên mỗi dữ liệu được tính như trong câu lệnh INSERT. 246.492 * 9/1024 = 2.1664 nhỏ hơn một trang 8k. Tuy nhiên, chúng tôi phải tạo ít nhất một trang, vì vậy khi bạn tính 8 * chi phí là 0,01, nó đặt chúng tôi chỉ cao hơn một chút so với ước tính 0,073832. Đó là dự đoán của tôi, và đó là một phỏng đoán. Tuy nhiên, tôi biết rằng có chi phí không đáng kể


Cảm ơn Grant vì đã đâm nó. Bạn đã đến gần hơn tôi có với bất cứ điều gì tôi đã mơ ước.
SpaceGhost440

2

Grant, tôi tin rằng một đồng nghiệp (Dennis Rogers) và tôi đã trả lời câu hỏi. Ở đây xuất hiện công thức dứt khoát mà SSMS sử dụng để tính chi phí vận hành và% chi phí.

Chi phí khai thác ước tính == @EstimatedTotalSubtreeCost - Sum (Trẻ em ngay lập tức @ Ước tínhTotalSubtreeCost)

Phần trăm chi phí khai thác ước tính = Chi phí vận hành ước tính / StmtSimple @ StatementSubTreeCost * 100

Tôi đã thử nghiệm điều này với một số kế hoạch và điều này dường như được chú ý.

Để biểu diễn phép tính trên dưới dạng xpath, nó biến thành:

@EstimatedTotalSubtreeCost - sum(./descendant::s:RelOp[1]/../s:RelOp/@EstimatedTotalSubtreeCost) 

Tổng tìm thấy hậu duệ đầu tiên thuộc loại RelOp, sau đó sao lưu một cấp và lấy tất cả các RelOps ở cấp đó và trích xuất Ước tínhTotalSubtreeCost của chúng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.