用户定义函数用于存储过程。用户定义函数返回标量值。遵循用户定义函数中使用的逻辑
CREATE FUNCTION [dbo].[udf_Test] ( @Code varchar(10), )
RETURNS bit AS
BEGIN
DECLARE @bFlag bit
SELECT @bFlag = COUNT(id)
FROM tbL1
WHERE Code = @Code
IF @bFlag = 0
BEGIN
SELECT @bFlag = COUNT(id)
FROM tbl2
WHERE LTRIM(RTRIM(Code)) = @Code
END
IF @bFlag = 0
BEGIN
SELECT @bFlag = COUNT(id)
FROM tbl3
WHERE LTRIM(RTRIM(Code)) = @Code
END
IF @bFlag = 0
BEGIN
SELECT @bFlag = COUNT(id)
FROM tbl4
WHERE LTRIM(RTRIM(Code)) = @Code
END
RETURN @bFlag
这是提高上述用户定义函数性能的正确方法吗?
答案 0 :(得分:8)
提高性能的最佳方法是完全抛弃UDF。
我发生的一件事就是
LTRIM(RTRIM(Code)) = @Code
不是sargable所以每次调用(即外部查询中返回的每一行)都可能导致最多4次表扫描。
如果在查询中使用内联的CASE表达式替换UDF中的逻辑,则可能会得到much superior execution plan。即使你不能使谓词至少变得可思考,它也会允许优化器探索不同的连接策略,例如散列连接,而不是强制重复扫描相同的表。
答案 1 :(得分:2)
现在......
WHERE LTRIM(RTRIM(Code)) = @Code;
使用ltrim(rtrim(..将阻止索引被使用。
理想情况下,您应该将ltrim(rtrim(Code))
的结果作为索引col,以便可以在WHERE子句中使用索引。这会加快速度。
当@bFlag = COUNT(id)
为int且@bFlag
为int时设置COUNT(id)
并不是那么好!你真的应该使用CASE WHEN COUNT(id) > 0 THEN 1 ELSE 0 END
或其他。
但是,使用IF EXISTS
的方法更有效,因为只要找到符合条件的单行,这种方法就会短路。
即
DECLARE @bFlag bit
SELECT @bFlag = 0
IF EXISTS (SELECT 'x' FROM tbl1 where Code= @Code ) SELECT @bFlag = 1
-- etc.
RETURN @bFlag