23

次の中で、一方を他方よりも使用する利点は何ですか。

DATEPART(YEAR, GETDATE())

とは対照的に:

YEAR(GETDATE())

性能差はありますか?もしそうなら、どれが最速ですか?

4

2 に答える 2

30

違いはありません。実行プランでは、両方がとして変換されdatepart(year,getdate())ます。

これは、SQL Server 2005、2008、および2012に当てはまります。

select datepart(year, getdate())
from (select 1 x) x

select year(getdate())
from (select 1 x) x

実行計画。

<?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.0" Build="9.00.5057.00" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
  <BatchSequence>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="1" StatementEstRows="1" StatementId="1" StatementOptmLevel="TRIVIAL" StatementSubTreeCost="1.157E-06" StatementText="select datepart(year, getdate())&#xD;&#xA;from (select 1 x) x&#xD;&#xA;&#xD;" StatementType="SELECT">
          <StatementSetOptions ANSI_NULLS="false" ANSI_PADDING="false" ANSI_WARNINGS="false" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="false" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="false" />
          <QueryPlan DegreeOfParallelism="0" CachedPlanSize="8" CompileTime="23" CompileCPU="23" CompileMemory="64">
            <RelOp AvgRowSize="11" EstimateCPU="1.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Constant Scan" NodeId="0" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="1.157E-06">
              <OutputList>
                <ColumnReference Column="Expr1001" />
              </OutputList>
              <RunTimeInformation>
                <RunTimeCountersPerThread Thread="0" ActualRows="1" ActualEndOfScans="1" ActualExecutions="1" />
              </RunTimeInformation>
              <ConstantScan>
                <Values>
                  <Row>
                    <ScalarOperator ScalarString="datepart(year,getdate())">
                      <Identifier>
                        <ColumnReference Column="ConstExpr1002">
                          <ScalarOperator>
                            <Intrinsic FunctionName="datepart">
                              <ScalarOperator>
                                <Const ConstValue="(0)" />
                              </ScalarOperator>
                              <ScalarOperator>
                                <Intrinsic FunctionName="getdate" />
                              </ScalarOperator>
                            </Intrinsic>
                          </ScalarOperator>
                        </ColumnReference>
                      </Identifier>
                    </ScalarOperator>
                  </Row>
                </Values>
              </ConstantScan>
            </RelOp>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
    <Batch>
      <Statements>
        <StmtSimple StatementCompId="2" StatementEstRows="1" StatementId="2" StatementOptmLevel="TRIVIAL" StatementSubTreeCost="1.157E-06" StatementText="select year(getdate())&#xD;&#xA;from (select 1 x) x" StatementType="SELECT">
          <StatementSetOptions ANSI_NULLS="false" ANSI_PADDING="false" ANSI_WARNINGS="false" ARITHABORT="true" CONCAT_NULL_YIELDS_NULL="false" NUMERIC_ROUNDABORT="false" QUOTED_IDENTIFIER="false" />
          <QueryPlan DegreeOfParallelism="0" CachedPlanSize="8" CompileTime="0" CompileCPU="0" CompileMemory="64">
            <RelOp AvgRowSize="11" EstimateCPU="1.157E-06" EstimateIO="0" EstimateRebinds="0" EstimateRewinds="0" EstimateRows="1" LogicalOp="Constant Scan" NodeId="0" Parallel="false" PhysicalOp="Constant Scan" EstimatedTotalSubtreeCost="1.157E-06">
              <OutputList>
                <ColumnReference Column="Expr1001" />
              </OutputList>
              <RunTimeInformation>
                <RunTimeCountersPerThread Thread="0" ActualRows="1" ActualEndOfScans="1" ActualExecutions="1" />
              </RunTimeInformation>
              <ConstantScan>
                <Values>
                  <Row>
                    <ScalarOperator ScalarString="datepart(year,getdate())">
                      <Identifier>
                        <ColumnReference Column="ConstExpr1002">
                          <ScalarOperator>
                            <Intrinsic FunctionName="datepart">
                              <ScalarOperator>
                                <Const ConstValue="(0)" />
                              </ScalarOperator>
                              <ScalarOperator>
                                <Intrinsic FunctionName="getdate" />
                              </ScalarOperator>
                            </Intrinsic>
                          </ScalarOperator>
                        </ColumnReference>
                      </Identifier>
                    </ScalarOperator>
                  </Row>
                </Values>
              </ConstantScan>
            </RelOp>
          </QueryPlan>
        </StmtSimple>
      </Statements>
    </Batch>
  </BatchSequence>
</ShowPlanXML>
于 2013-02-13T09:46:49.910 に答える
17

実際には、決定論的関数YEAR(..)と見なされるため、使用することが望ましいので、これを計算列定義で使用する場合

ALTER TABLE dbo.MyTable
ADD YearOfDate AS YEAR(SomeDateColumn)

この列を永続化する (そしてテーブルに格納する)ことができます。

ALTER TABLE dbo.MyTable
ADD YearOfDate AS YEAR(SomeDateColumn) PERSISTED

これは機能しません(DATEPART(YEAR, SomeDateColumn)理由は聞かないでください。ヒューリスティックに気づいただけです)。

MONTH(SomeDate)同じことがvs.にも当てはまりますDATEPART(MONTH, SomeDate)

日付の月と年 (など) に基づいて選択する必要があるテーブルがある場合、月と年を永続化された計算SalesDate列として持つ(そしてそれらにインデックスを付ける) と、パフォーマンスが大幅に向上する可能性があります。

于 2013-02-13T10:36:46.763 に答える