我有一个表值内联 UDF。我想过滤该 UDF 的结果以获得一个特定值。当我使用常量参数指定过滤器时,一切都很好,并且性能几乎是瞬时的。当我使用可变参数指定过滤器时,它会花费明显更大的时间块,大约是逻辑读取的 500 倍和持续时间的 20 倍。
执行计划显示,在可变参数情况下,直到过程的最后阶段才应用过滤器,从而导致多次索引扫描,而不是在常量情况下执行的查找。
我想我的问题是:为什么,既然我指定了一个对索引字段具有高度选择性的过滤器参数,那么当该参数位于变量中时,我的性能会变得很糟糕吗?我能做些什么吗?
和查询中的解析函数有关系吗?
以下是我的疑问:
CREATE FUNCTION fn_test()
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
SELECT DISTINCT GCN_SEQNO, Drug_package_version_ID
FROM
(
SELECT COALESCE(ndctbla.GCN_SEQNO, ndctblb.GCN_SEQNO) AS GCN_SEQNO,
dpv.Drug_package_version_ID, ROW_NUMBER() OVER (PARTITION BY dpv.Drug_package_version_id ORDER BY
ndctbla.GCN_SEQNO DESC) AS Predicate
FROM dbo.Drug_Package_Version dpv
LEFT JOIN dbo.NDC ndctbla ON ndctbla.NDC = dpv.Sp_package_code
LEFT JOIN dbo.NDC ndctblb ON ndctblb.SPC_NDC = dpv.Sp_package_code
) iq
WHERE Predicate = 1
GO
GRANT SELECT ON fn_test TO public
GO
-- very fast
SELECT GCN_SEQNO
FROM dbo.fn_test()
WHERE Drug_package_version_id = 10000
GO
-- comparatively slow
DECLARE @dpvid int
SET @dpvid = 10000
SELECT GCN_SEQNO
FROM dbo.fn_test()
WHERE Drug_package_version_id = @dpvid
通过 UDF 创建新投影后,不能期望您的索引仍将应用于在原始表上建立索引并包含在投影中的列。当您对投影进行过滤(而不是在 UDF 中针对带有索引的原始表进行过滤)时,索引将不再适用。
您想要做的是将函数参数化以接收参数。
如果您发现要设置参数的字段太多,那么您可能需要查看索引视图,因为您可以创建投影并为其建立索引,然后对其运行查询。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)