日期范围查询方法的性能比较
以下两个查询中,哪一个更快?该表包含超过100M条记录。所以我只想知道在where子句中使用ISNULL是否与首先为变量赋值并仅在where子句中使用变量相同?日期范围查询方法的性能比较
declare @dt datetime
select COUNT(*) from pandl
where PaymentDate >= ISNULL(@dt, convert(nvarchar(10),getdate(), 121))
select @dt = ISNULL(@dt, convert(nvarchar(10),getdate(), 121))
select COUNT(*) from pandl
where PaymentDate >= @dt
第二个会更好。从where子句中调用函数将使查询优化器使用扫描而不是搜索。换句话说,你会得到一个不太理想的执行计划
+1 Hola Brandon! – 2012-02-17 14:02:00
从'where'子句检查的值*上调用函数*肯定会导致扫描。但是我的印象是,如果返回值在调用的整个过程中不会改变,SQL Server就足够了解调用该函数的次数。 – cHao 2012-02-17 14:06:58
@ cHao是的,这是真的,问题中的两个版本都不会导致扫描。我只是给了布兰登第一个+1,因为我同意他的第一句话。 :-) – 2012-02-17 14:09:45
我会建议一个稍微不同的方法,避免稍微昂贵的转换为字符串,并使用稍小的数据类型来存储日期(因为你不喜欢“T需要分分钟的间隔,如果你只在乎时间的界限):
DECLARE @dt SMALLDATETIME;
SET @dt = DATEADD(DAY, DATEDIFF(DAY, '19000101', CURRENT_TIMESTAMP), '19000101'); --*
SELECT COUNT(*) FROM dbo.pandl
WHERE PaymentDate >= @dt;
如果你想继续使用转换为字符串,使用CHAR(10)
- 我不认为风格121将生成需要Unicode支持的任何日期格式。
*
是的,你可以做到这一点没有外DATEADD
但与新的类型,如DATE
FWIW,如果你没有一个指标,它是不会影响计划:在文本模式下
运行,检查显示的执行计划。
我想在StackExchange这些日期列之一将有一个索引,但我没有找到一个。
除此之外,我在这方面的其他答案 - 不要不必要地使用nvarchar,不要将日期转换为字符串没有很好的理由,不要使用可以在查询之外更易读的函数在查询内部(如果不需要,请不要在查询中使用函数)。
+1显示实际执行计划! – Justin 2012-02-17 14:20:26
你是否运行它们以查看哪个更快?您是否使用过SQL Profiler来查看每个查询的执行计划? – Pondlife 2012-02-17 13:54:28
你想使用多少个不同的“现在”值?第二个查询捕获当前的日期/时间,如果需要的话,然后搜索。 – HABO 2012-02-17 14:04:31
@ user92546这是一个很好的观点,但仅仅为了添加一些信息,即使'getdate()'在第一个查询过程中被多次评估(我将不得不运行一些测试来验证),因为转换将它舍入了它直到今天,如果查询在午夜之前开始并且仍然在处理(并且在午夜之后将新值赋给'getdate()'),那才真正重要。我完全同意你的看法,一次分配更好,只是想澄清什么时候它可能非常糟糕,而不是“最好”。 – 2012-02-17 14:18:26