SQL Server评估表值函数两次

时间:2018-03-12 19:27:34

标签: sql-server tsql user-defined-functions database-performance

从表值函数中选择时,SQL Server会采用一种非常奇怪的执行计划:

DECLARE @buffer float = 55.0
DECLARE @day date = '09.03.2018'
SELECT *
  FROM [dbo].[fct_foo] ( @buffer, @day )
GO

奇怪的是,该函数似乎被评估了两次,手动执行函数内部的代码要快7倍。函数estimateRows =“1”的第一次执行,并且ActualRows =“0”。 函数estimateRows =“1”的第二次执行并且具有ActualRows =“1992”,这是正确结果表的大小。 任何想法为什么评价执行两次?获得正确的行esitmations的一般提示也非常感谢:) 我知道另一个问题here,但它对这个问题没有帮助。

the executionplan picture

<?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="11.0.5058.0" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="3" StatementEstRows="1" StatementId="1" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" StatementSubTreeCost="0.00328626" StatementText="SELECT *  FROM [dbo].[fct_foo] ( @buffer, @day )&#xD;&#xA;" StatementType="SELECT" QueryHash="0x2247A3EEF95ACB75" QueryPlanHash="0x58FA3B5B0BE3CD9F" 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="1" CompileCPU="1" CompileMemory="120">
            <MemoryGrantInfo SerialRequiredMemory="0" SerialDesiredMemory="0" />
            <OptimizerHardwareDependentProperties EstimatedAvailableMemoryGrant="131072" EstimatedPagesCached="32768" EstimatedAvailableDegreeOfParallelism="2" />
            <RelOp AvgRowSize="4575" EstimateCPU="2E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Sequence" NodeId="0" Parallel="false" PhysicalOp="Sequence" EstimatedTotalSubtreeCost="0.00328626">
              <OutputList>
                <ColumnReference Database="[db_BA_LSA_QZ]" Schema="[dbo]" Table="[fct_foo]" Column="col_a" />
                <ColumnReference Database="[db_BA_LSA_QZ]" Schema="[dbo]" Table="[fct_foo]" Column="col_b" />
              </OutputList>
              <RunTimeInformation>
                <RunTimeCountersPerThread Thread="0" ActualRows="1992" ActualEndOfScans="1" ActualExecutions="1" />
              </RunTimeInformation>
              <Sequence>
                <RelOp AvgRowSize="9" EstimateCPU="1.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Table-valued function" NodeId="1" Parallel="false" PhysicalOp="Table-valued function" EstimatedTotalSubtreeCost="1.157E-06">
                  <OutputList />
                  <RunTimeInformation>
                    <RunTimeCountersPerThread Thread="0" ActualRebinds="1" ActualRewinds="0" ActualRows="0" ActualEndOfScans="0" ActualExecutions="1" />
                  </RunTimeInformation>
                  <TableValuedFunction>
                    <DefinedValues />
                    <Object Database="[db_BA_LSA_QZ]" Schema="[dbo]" Table="[fct_foo]" />
                    <ParameterList>
                      <ScalarOperator ScalarString="[@buffer]">
                        <Identifier>
                          <ColumnReference Column="@buffer" />
                        </Identifier>
                      </ScalarOperator>
                      <ScalarOperator ScalarString="[@day]">
                        <Identifier>
                          <ColumnReference Column="@day" />
                        </Identifier>
                      </ScalarOperator>
                    </ParameterList>
                  </TableValuedFunction>
                </RelOp>
                <RelOp AvgRowSize="4575" EstimateCPU="0.0001581" EstimateIO="0.003125" EstimateRebinds="0" EstimateRewinds="0" EstimatedExecutionMode="Row" EstimateRows="1" LogicalOp="Table Scan" NodeId="4" Parallel="false" PhysicalOp="Table Scan" EstimatedTotalSubtreeCost="0.0032831" TableCardinality="0">
                  <OutputList>
                    <ColumnReference Database="[db_BA_LSA_QZ]" Schema="[dbo]" Table="[fct_foo]" Column="col_a" />
                    <ColumnReference Database="[db_BA_LSA_QZ]" Schema="[dbo]" Table="[fct_foo]" Column="col_b" />
                  </OutputList>
                  <RunTimeInformation>
                    <RunTimeCountersPerThread Thread="0" ActualRows="1992" ActualEndOfScans="1" ActualExecutions="1" />
                  </RunTimeInformation>
                  <TableScan Ordered="false" ForcedIndex="false" ForceScan="false" NoExpandHint="false">
                    <DefinedValues>
                      <DefinedValue>
                        <ColumnReference Database="[db_BA_LSA_QZ]" Schema="[dbo]" Table="[fct_foo]" Column="col_a" />
                      </DefinedValue>
                      <DefinedValue>
                        <ColumnReference Database="[db_BA_LSA_QZ]" Schema="[dbo]" Table="[fct_foo]" Column="col_b" />
                      </DefinedValue>
                    </DefinedValues>
                    <Object Database="[db_BA_LSA_QZ]" Schema="[dbo]" Table="[fct_foo]" />
                  </TableScan>
                </RelOp>
              </Sequence>
            </RelOp>
            <ParameterList>
              <ColumnReference Column="@day" ParameterRuntimeValue="'2018-03-09'" />
              <ColumnReference Column="@buffer" ParameterRuntimeValue="(5.500000000000000e+001)" />
            </ParameterList>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>

0 个答案:

没有答案