如何改进包含嵌套子查询的SQL Server查询

时间:2010-07-08 00:40:35

标签: sql sql-server optimization subquery

我的老板给了我这个SQL查询并告诉他改进/优化它

DECLARE @pol_0 int, @pol_1 int, @pol_2 int, @pol_3 int, @pol_4 int, @pol_5plus int,
    @peril_0 int, @peril_1 int, @peril_2 int, @peril_3 int, @peril_4 int, @peril_5plus int,
    @loc_1 int, @loc_2_10 int, @loc_11_100 int, @loc_101_1000 int, @loc_1001_5000 int, @loc_5001plus int,
    @locfass int, @polfass int, @pollim int, @polattpt int, @polded int, @maxded int, @polres int, @sublimit int,
    @sitelim int, @siteded int, @SS int, @WX int, @QS int, @CAT int, @CORP int, @SL int,
    @ty_port int, @ty_acct int, @ty_pol int, @ty_loc int,
    @2mod_eq_0 int, @2mod_eq_1_10 int, @2mod_eq_11_20 int, @2mod_eq_21_27 int,
    @2mod_hu_0 int, @2mod_hu_1_10 int, @2mod_hu_11_20 int, @2mod_hu_21_27 int

SELECT @pol_0 = COUNT(CASE CNT WHEN 0 THEN 99 ELSE NULL END),
   @pol_1 = COUNT(CASE CNT WHEN 1 THEN 99 ELSE NULL END),
   @pol_2 = COUNT(CASE CNT WHEN 2 THEN 99 ELSE NULL END),
   @pol_3 = COUNT(CASE CNT WHEN 3 THEN 99 ELSE NULL END),
   @pol_4 = COUNT(CASE CNT WHEN 4 THEN 99 ELSE NULL END),
   @pol_5plus = COUNT(CASE WHEN CNT >= 5 THEN 99 ELSE NULL END) 
FROM   ( SELECT  ACCGRP.ACCGRPID,
                COUNT(POLICYID) AS CNT
       FROM     ACCGRP
                LEFT OUTER JOIN POLICY
                ON       ACCGRP.ACCGRPID = POLICY.ACCGRPID
       GROUP BY ACCGRP.ACCGRPID
       )

我的第一个想法是丢弃DECLARE,然后将COUNT转换为类似

的内容
SELECT 
(select COUNT(CASE CNT WHEN 0 THEN 99 ELSE NULL END),
(select COUNT(CASE CNT WHEN 1 THEN 99 ELSE NULL END),
(select COUNT(CASE CNT WHEN 2 THEN 99 ELSE NULL END),
(select COUNT(CASE CNT WHEN 3 THEN 99 ELSE NULL END),
(select COUNT(CASE CNT WHEN 4 THEN 99 ELSE NULL END),
(select COUNT(CASE CNT WHEN >= 5 THEN 99 ELSE NULL END) FROM

但是FROM子句有一个嵌套的子查询

FROM (SELECT ACCGRP.ACCGRPID, COUNT(POLICYID) AS CNT FROM ACCGRP LEFT OUTER JOIN POLICY ON ACCGRP.ACCGRPID = POLICY.ACCGRPID
GROUP BY ACCGRP.ACCGRPID)

有人建议我删除嵌套的子查询,但我不确定什么是嵌套子查询的更好的替代方法。任何建议将不胜感激!

2 个答案:

答案 0 :(得分:1)

这个查询真的很慢吗?

如果是这样,那么你应该得到一个执行计划,并根据结果进行优化。

如果没有,那么没有什么可以优化的! : - )

有一种常见的误解,即嵌套子查询很慢,但事实并非如此。在特定情况下,嵌套子查询可能会导致性能问题,但在一般情况下,SQL服务器通常会将嵌套子查询优化为与连接类似的执行计划。

答案 1 :(得分:0)

因此,子查询确定每个ACCGRPID的策略数。你有ACCGRP.ACCGRPIDPOLICY.ACCGRPID的索引吗?如果是这样的话,我看不到太多的优化范围(除了预先计算),因为它是第二步的必要输入。

你没有在5之后使用COUNT值,所以它可能会扫描一些不必要的行,但我想不出一种避免这种情况的方法,除非这是一个非常值得尝试的大部分记录。

如果COUNT(POLICY.ACCGRPID)没有改变语义,可能有帮助COUNT(POLICYID)可能会有帮助,因为POLICY.ACCGRPID已经在查询的其他地方使用过了,它可能会避免不必要的查找或允许要使用的索引较窄。您必须查看查询计划,看看这是否有所不同。可能如果它有not null约束,SQL Server无论如何都会进行此优化。

为什么要求您对其进行优化?是否会导致性能问题?如果是这样,你可以发布执行计划吗?