我目前正在研究一个特别复杂的用例。简化如下:)Sql子查询函数的性能
首先,客户端记录与服务集合具有多对一的关系,也就是说,单个客户端可能有多个与之关联的服务。
在我的触发器中,我正在编写一个Query,它根据特定条件返回客户端的ID。的标准如下,
- 如果至少一个服务是B型的,并且没有A型的服务存在,返回ID
- 如果至少一个服务是C型的,并没有类型的服务B或A存在,返回ID
- 如果至少一个服务的类型d,也没有C型或B或A的服务存在,返回ID
和我目前的做法是形成类似查询到下面的一个
SELECT c.ClientId
FROM
Clients AS c
-- actually INNER JOIN is superfluous in this sample, but required for
-- other auxilliary criteria i have left out. illustrates relationship
-- between Clients and Services table
INNER JOIN Services AS s ON c.ClientId = s.ClientId
WHERE
-- has at least one service of type B, no A
(EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'B')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'A'))) OR
-- has at least one service of type C, no B, no A
(EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'C')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'B')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'A'))) OR
-- has at least one service of type D, no C, no B, no A
(EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'D')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'C')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'B')) AND
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'A')))
其中[dbo].[Get_ServicesByClientIdAndType]
是为指定的客户端ID和服务类型返回关联服务的函数。到
-- this query is actually significantly more complex than shown
-- below, but this illustrates use of parameters client id and
-- service type
SELECT s.ServiceType
FROM
Services AS s
WHERE
s.ClientId = @clientId AND
s.ServiceType = @serviceType
类似的假设这是表达这种用例优化手段,将功能[dbo].[Get_ServicesByClientIdAndType]
子查询被缓存或不改变服务参数必须使用新的评估每个调用? [我正在调用这个东西像9次!运行Sql Server 2005]
我知道Sql Server 2005支持一些子查询优化,比如缓存结果,但我不确定在什么情况下或者如何形成我的子查询[或者函数]我充分利用了Sql Server的功能。
编辑:审查我的标准之上,不能让一个唠叨的感觉的东西走得掉。我在我的脑海一些逻辑发挥各地,以及与此[更为简单配方
SELECT c.ClientId
FROM
Clients AS c
INNER JOIN Services AS s ON c.ClientId = s.ClientId
WHERE
NOT EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'A')) AND
(EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'B')) OR
EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'C')) OR
EXISTS (SELECT * FROM Get_ServicesByClientIdAndType (c.ClientId, 'D')))
本质上来了,不存在的情况涉及B会导致排斥反应,同样,对于C和d,所以任何配置可以接受。我们只关心A不存在于任何选择中。 Arg!查理·布朗!
留下两个表达式进行审查,我还是很欣赏有关SQL Server的性能WRT用户自定义函数的响应。
哇,非常酷。它是有道理的,基本上是在单个子查询中列出事件,然后从中进行选择。我只在一个更简单但等同的表达式中重申了我的条件 - 对您的解决方案的唯一影响是更简单的外部WHERE子句WHERE A.ServiceA = 0 AND(A.ServiceB> 0或A.ServiceC> 0或A.ServiceD> 0 )' – 2009-11-06 21:14:51