Sql 两个脚本—何时以及如何将函数应用于WHERE子句
Sql 两个脚本—何时以及如何将函数应用于WHERE子句,sql,sql-server,query-tuning,Sql,Sql Server,Query Tuning,WH.dbo.vw_FactTable是一个巨大的表,100行,在DateKey 这几乎是瞬间发生的: 1. SELECT COUNT(*) FROM WH.dbo.vw_FactTable bi WHERE DateKey >= 20130101 AND DateKey <= 20130110 1。 选择计数(*) 来自WH.dbo.vw_事实表bi 其中DateKey>=20130101和 日期键='2013年1月1日' CONVERT(DATE
WH.dbo.vw_FactTable
是一个巨大的表,100行,在DateKey
这几乎是瞬间发生的:
1.
SELECT COUNT(*)
FROM WH.dbo.vw_FactTable bi
WHERE DateKey >= 20130101 AND
DateKey <= 20130110
1。
选择计数(*)
来自WH.dbo.vw_事实表bi
其中DateKey>=20130101和
日期键='2013年1月1日'
CONVERT(DATETIME,CONVERT(CHAR(8),DateKey,112))在第二次查询中,当您使用where子句(CONVERT)中的函数时,此函数的结果将在运行时进行评估,SQL Server查询引擎必须扫描整个表以获得必要的数据。在第二次查询中,当您使用where子句中的函数时(Convert),此函数的结果将在运行时进行评估,SQL Server查询引擎必须扫描整个表以获取必要的数据。人们已经在注释中击中了它的头部,重新构造字段将使索引中性化,这将执行与第一次查询类似的操作:
SELECT COUNT(*)
FROM WH.dbo.vw_FactTable bi
WHERE DateKey BETWEEN CAST(CAST(REPLACE(CAST('01 JAN 2013' AS DATE),'-','')AS VARCHAR(12))AS INT)
AND CAST(CAST(REPLACE(CAST('10 JAN 2013' AS DATE),'-','')AS VARCHAR(12))AS INT)
人们已经在评论中击中了它的头部,重新构造字段将使索引中性化,这将执行与第一个查询类似的操作:
SELECT COUNT(*)
FROM WH.dbo.vw_FactTable bi
WHERE DateKey BETWEEN CAST(CAST(REPLACE(CAST('01 JAN 2013' AS DATE),'-','')AS VARCHAR(12))AS INT)
AND CAST(CAST(REPLACE(CAST('10 JAN 2013' AS DATE),'-','')AS VARCHAR(12))AS INT)
通过对约束执行所有这些转换,您将失去对DateKey列使用索引的能力。您最好将参数与表数据进行转换。不要对数据库列执行日期转换(因为它必须对每一行执行)。对文本进行日期转换。查询1是并使用索引查找。查询2不是并提供扫描。您不能调整查询2以提供与1相同的计划。在某些情况下,创建计算列和索引将允许使用索引,但这无论如何不是计算列的确定性转换。@MartinSmith hiMartin-“sargable”?你同意BM21吗?我为“sargable”添加了一个wiki链接是的,这与@bmorgan21所说的是一样的。通过对约束进行所有这些转换,您将失去对DateKey列使用索引的能力。您最好将参数与表数据进行转换。不要对数据库列进行日期转换(因为它必须对每一行都进行转换)。对文本进行日期转换。查询1是并使用索引查找。查询2不是并提供扫描。您不能调整查询2以提供与1相同的计划。在某些情况下,创建计算列和索引将允许使用索引,但这无论如何不是计算列的确定性转换。@MartinSmith hiMartin—“sargable”?你同意BMOrgang21吗?我为“sargable”添加了一个wiki链接,是的,它与@BMOrgang21所说的是一样的。好的-我来看看展示计划上说的:就像你说的希望与1
一样好的-我来看看展示计划上说的:就像你说的希望与1