Как улучшить запрос SQL Server, содержащий вложенный подзапрос - PullRequest
0 голосов
/ 08 июля 2010

Мой босс дал мне этот 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 ]

1 голос
/ 08 июля 2010

Является ли этот запрос действительно медленным?

Если это так, то вы должны получить план выполнения и оптимизировать его на основе результатов.

Если нет, то оптимизировать нечего!: -)

Существует распространенное заблуждение, что вложенные подзапросы медленные, однако это просто не тот случай.В определенных обстоятельствах вложенный подзапрос может вызвать проблемы с производительностью, однако в общем случае часто вложенные подзапросы оптимизируются SQL-сервером до тех же планов выполнения, что и объединения.

0 голосов
/ 08 июля 2010

Таким образом, подзапрос определяет количество политик на ACCGRPID.У вас уже есть индексы на ACCGRP.ACCGRPID и POLICY.ACCGRPID?Если это так, я не вижу большой возможности оптимизировать это действительно (кроме предварительного расчета), так как это необходимый вклад во второй шаг.

Вы не используете значение COUNT после 5, поэтому оно может сканировать некоторые ненужные строки, но я не могу придумать, как этого избежать, и, вероятно, не стоит пытаться, если это не былобольшая часть записей.

Возможно, выполнение COUNT(POLICY.ACCGRPID) вместо COUNT(POLICYID) может помочь, если оно не меняет семантику, поскольку POLICY.ACCGRPID уже используется в другом месте запроса и может избежать ненужныхискать или разрешить использовать более узкий индекс.Вы должны взглянуть на план запроса, чтобы увидеть, если это имеет какое-либо значение.Возможно, если он имеет ограничение not null, SQL Server все равно выполнит эту оптимизацию.

Почему вас попросили оптимизировать его?Это вызывает проблемы с производительностью?Если да, можете ли вы опубликовать план выполнения?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...