我有一个情况,我需要翻译(查找)同一个表中的多个值。我编写的第一种方法是使用子查询:
SELECT
(SELECT id FROM user WHERE user_pk = created_by) AS creator,
(SELECT id FROM user WHERE user_pk = updated_by) AS updater,
(SELECT id FROM user WHERE user_pk = owned_by) AS owner,
[name]
FROM asset
由于我经常使用这个子查询(也就是说,我有大约 50 个包含这些字段的表),并且我可能需要向子查询添加更多代码(例如,“AND active = 1”),我想我' d 将它们放入用户定义的函数中UDF http://en.wikipedia.org/wiki/User-defined_function并使用它。但使用该 UDF 的性能非常糟糕。
CREATE FUNCTION dbo.get_user ( @user_pk INT )
RETURNS INT
AS BEGIN
RETURN ( SELECT id
FROM ice.dbo.[user]
WHERE user_pk = @user_pk )
END
SELECT dbo.get_user(created_by) as creator, [name]
FROM asset
#1 的性能不到 1 秒。 #2 的表演大约 30 秒...
为什么,或者更重要的是,有什么方法可以在 SQL Server 2008 中编码,这样我就不必使用这么多子查询?
Edit:
只是稍微解释一下何时有用。当我想要为用户提供文本时,这个简单的查询(即获取用户 ID)会变得更加复杂,因为我必须加入个人资料以获取语言,并加入公司以查看是否应该获取该语言'相反,从那里编辑,并使用翻译表来获取翻译后的文本。对于大多数这些查询,性能是可读性和可维护性的次要问题。
UDF 对于查询优化器来说是一个黑匣子,因此它会针对每一行执行。
您正在执行逐行游标。对于资产中的每一行,在另一个表中查找 id 三次。当您使用标量或多语句 UDF 时会发生这种情况(内联 UDF 只是扩展到外部查询的宏)
关于这个问题的许多文章之一是“标量函数、内联和性能:无聊帖子的有趣标题 http://dataeducation.com/scalar-functions-inlining-and-performance-an-entertaining-title-for-a-boring-post/".
可以优化子查询以关联并避免逐行操作。
你真正想要的是这样的:
SELECT
uc.id AS creator,
uu.id AS updater,
uo.id AS owner,
a.[name]
FROM
asset a
JOIN
user uc ON uc.user_pk = a.created_by
JOIN
user uu ON uu.user_pk = a.updated_by
JOIN
user uo ON uo.user_pk = a.owned_by
2019 年 2 月更新
SQL Server 2019开始修复这个问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)