【发布时间】:2019-01-23 20:33:53
【问题描述】:
虽然下面的查询非常适合我的使用,但我试图了解是否有优化的方法,因为它在 UNION 的两个语句中使用相同的嵌套子查询。我的直觉认为应该有一种方法可以查找子查询一次并将该结果用于 UNION 的两个部分,但是在尝试跨 UNION 使用 join 时我遇到了语法问题。
SELECT ClientLocalName, ClientLocalID, ClientMasterID, 1 HierarchyType
FROM dbo.ClientLocal
WHERE clientLocalID =
ANY (SELECT HierarchyItem FROM dbo.ClientPhone WHERE PhoneNumber LIKE '%0123456789')
UNION
SELECT ClientMasterName, '0', clientMasterID, 2
FROM dbo.ClientMaster
WHERE clientMasterID =
ANY (SELECT HierarchyItem FROM dbo.ClientPhone WHERE PhoneNumber LIKE '%0123456789')
ORDER BY HierarchyType ASC;
为了帮助解释为什么需要原始查询,请想象一个“本地”客户端和“主”客户端的概念——本地客户端与主客户端绑定,但主客户端可能有也可能没有本地客户。同样,与每个相关联的电话号码只能与本地客户端或主客户端绑定(因此在第二个语句中,本地客户端 ID 硬编码为“0”——因为没有关联)。
顺便说一下,这将针对 Microsoft SQL Server 2008 R2 运行。
【问题讨论】:
-
只是因为您重复了代码,并不一定意味着它会被重复评估。优化器很可能会发现这是重复的,并重用第一次评估的结果。除非,重新评估当然似乎更合适。如果只是重复代码,请使用提供的 CTE 解决方案。
-
这个查询中可能有很多需要优化的地方。首先,我看不出这个查询是如何运行的,因为你不能
UNIONClientLocalName和ClientMasterName除非这些列具有相同的名称。你能提供一点样本数据和你的预期结果吗?ClientPhone的 CTE 将起作用,但这实际上是您想要获得的数据吗? -
@Shawn 列的名称无关紧要,只要联合中的数据类型相同。查询确实工作得很好。无论如何,卢卡斯的回答提供了我正在寻找的东西。
-
@stickybit 是对的,但是真实的代码在重复代码中会有更多的条件,所以这里有一个很好的鼓励不要重复。
-
@stickybit:其实重复的代码必然会被多次求值。当然,基本数据只需要加载到缓存中一次,但实际执行的频率是按要求完成的。请参阅下面的示例。
标签: sql tsql subquery query-optimization union