在以下中使用一个优于另一个的优点是什么:
DATEPART(YEAR, GETDATE())
Run Code Online (Sandbox Code Playgroud)
相反:
YEAR(GETDATE())
Run Code Online (Sandbox Code Playgroud)
是否存在性能差异?如果是这样,哪一个最快?
Mik*_*son 26
没有区别.在执行计划中,两者都被翻译为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
Run Code Online (Sandbox Code Playgroud)
执行计划.
<?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())
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="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())
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>
Run Code Online (Sandbox Code Playgroud)
mar*_*c_s 16
实际上 - 使用YEAR(..)对我来说最好,因为它被认为是一个确定性函数,所以如果我在计算列定义中使用它
ALTER TABLE dbo.MyTable
ADD YearOfDate AS YEAR(SomeDateColumn)
Run Code Online (Sandbox Code Playgroud)
我可以将此列保留(并将其存储到表中):
ALTER TABLE dbo.MyTable
ADD YearOfDate AS YEAR(SomeDateColumn) PERSISTED
Run Code Online (Sandbox Code Playgroud)
这并没有对工作DATEPART(YEAR, SomeDateColumn)( -只注意到这个启发式不要问我为什么).
这同样适用于MONTH(SomeDate)对DATEPART(MONTH, SomeDate).
如果您需要根据日期的月份和年份(例如SalesDate或某些东西)选择表格,那么将月份和年份作为持久计算列(并将其编入索引)可以大大提高性能.