【发布时间】:2010-10-01 19:04:32
【问题描述】:
情况如下:
我有一个带有日期时间参数的表值函数,以免说 tdf(p_date) ,
过滤大约 200 万行,选择列日期小于 p_date 的行,并在其他列上计算一些聚合值。
它工作得很好,但如果 p_date 是一个自定义标量值函数(在我的例子中返回一天结束),执行计划就会改变,查询从 1 秒到 1 分钟执行时间。
概念证明表 - 1K 产品,2M 行:
CREATE TABLE [dbo].[POC](
[Date] [datetime] NOT NULL,
[idProduct] [int] NOT NULL,
[Quantity] [int] NOT NULL
) ON [PRIMARY]
内联表值函数:
CREATE FUNCTION tdf (@p_date datetime)
RETURNS TABLE
AS
RETURN
(
SELECT idProduct, SUM(Quantity) AS TotalQuantity,
max(Date) as LastDate
FROM POC
WHERE (Date < @p_date)
GROUP BY idProduct
)
标量值函数:
CREATE FUNCTION [dbo].[EndOfDay] (@date datetime)
RETURNS datetime
AS
BEGIN
DECLARE @res datetime
SET @res=dateadd(second, -1,
dateadd(day, 1,
dateadd(ms, -datepart(ms, @date),
dateadd(ss, -datepart(ss, @date),
dateadd(mi,- datepart(mi,@date),
dateadd(hh, -datepart(hh, @date), @date))))))
RETURN @res
END
查询 1 - 效果很好
SELECT * FROM [dbo].[tdf] (getdate())
执行计划结束: 流聚合成本 13%
查询 2 - 不太好
SELECT * FROM [dbo].[tdf] (dbo.EndOfDay(getdate()))
执行计划结束: 流聚合成本 4%
【问题讨论】:
-
SQL 代码来准确说明您的意思会很有帮助。
-
我发布了复制执行计划变体所需的代码
标签: sql-server tsql sql-execution-plan user-defined-functions