状況は次のとおりです:
datetime パラメーターを持つテーブル値関数があります。たとえば、 tdf(p_date) とは言えません。これは、列の日付が p_date より小さい列を選択して約 200 万行をフィルター処理し、他の列の集計値を計算します。
それはうまく機能しますが、p_dateがカスタムスカラー値関数(私の場合は一日の終わりを返す)である場合、実行計画が変更され、クエリの実行時間が1秒から1分になります。
概念実証テーブル - 1,000 製品、2,000,000 行:
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% <--- クラスタ化インデックス スキャン コスト 86%
クエリ 2 - あまり良くない
SELECT * FROM [dbo].[tdf] (dbo.EndOfDay(getdate()))
実行計画の終了: ストリーム集約コスト 4% <--- フィルター コスト 12% <--- クラスター化インデックス スキャン コスト 86%