none
Query RRS feed

  • Pergunta

  •  

    estou com a seguinte dúvida:

    tenho essa query em uma stored procedure e é a primeira vez que eu vejo esse tipo, montando uma consulta dentro de uma variável varchar(4000);

     

    queria saber se tem diferença de performance com relação ao modo normal

     

     

    Code Snippet

    select @strSQL = 'SELECT DISTINCT tr.cod_ocor, tr.num_ctrl_ocor, tr.des_area_ocor, tr.cod_area_ocor, tr.des_ocor,
    tr.cod_moed_envo, tr.val_ocor_envo, tr.cod_moed_perd,

    tr.val_ocor_perd, tr.cod_moed_ganh, tr.val_ocor_ganh,

    tr.des_acao, tr.cod_stat, tr.dat_cadm_ocor, tr.des_logi_soli,

    tr.dat_ocor, tu.nom_comp, tr.dat_manu_soli, nom_coor = t5.nom_comp,

    tr.des_logi_coor, tr.des_obsv_coor, tr.dat_manu_coor,

    nom_supe = t4.nom_comp, tr.des_logi_supe, tr.des_obsv_supe,

    tr.dat_manu_supe, nom_dire = t3.nom_comp, tr.des_logi_dire,

    tr.des_obsv_dire, tr.dat_manu_dire, tr.cod_meti_1, tr.cod_meti_2,

    tr.cod_meti_3, tr.cod_meti_4, tr.cod_meti_5, tr.cod_risc,

    tr.cod_tipo_1, tr.cod_tipo_2, tr.cod_tipo_3, tr.cod_tipo_4, tr.cod_tipo_5,

    tr.cod_tipo_6, tr.cod_tipo_7, tr.des_outr_tipo, tr.val_qtde_tipo_1,

    tr.val_qtde_tipo_2
          ,des_logi_coor_cont = isnull(tc.des_logi_coor_cont, '''')
          ,des_nome_coor_cont = isnull(case when tc.des_logi_coor_cont <> '''' or tc.des_logi_coor_cont is not null then (select nom_comp from tbl_intr_usua where tc.des_logi_coor_cont = des_logi) else '''' end, '''')
          ,des_logi_supe_cont = isnull(tc.des_logi_supe_cont, '''')
          ,des_nome_supe_cont = isnull(case when tc.des_logi_supe_cont <> '''' or tc.des_logi_supe_cont is not null then (select nom_comp from tbl_intr_usua where tc.des_logi_supe_cont = des_logi) else '''' end, '''')
          ,des_logi_dire_cont = isnull(tc.des_logi_dire_cont, '''')
          ,des_nome_dire_cont = isnull(case when tc.des_logi_dire_cont <> '''' or tc.des_logi_dire_cont is not null then (select nom_comp from tbl_intr_usua where tc.des_logi_dire_cont = des_logi) else '''' end, '''')
     
          FROM   tbl_rod_ocor  tr


          left join tbl_rod_ocor_user  td
          on  td.cod_ocor  = tr.cod_ocor
       
          left join tbl_rod_ocor_cont tc
          on  tc.cod_ocor  = tr.cod_ocor
       
          inner join tbl_intr_usua  tu
          on  tu.des_logi  = tr.des_logi_soli
       
          left join tbl_intr_usua  t5
          on  t5.des_logi  = tr.des_logi_coor

          left join tbl_intr_usua  t4
          on  t4.des_logi  = tr.des_logi_supe
       
          inner join tbl_intr_usua  t3
          on  t3.des_logi  = tr.des_logi_dire

     

         WHERE

    tr.cod_stat >= ' + @p_cod_stat_inil + '
    AND  tr.cod_stat <= ' + @p_cod_stat_finl + char(13)

     

     

    segunda-feira, 3 de março de 2008 15:24

Respostas

  • Fernando, usualmente chamamos esse tipo de query de dinâmica, pois esta pode ou não alterar os parâmetros conforme alguma condição.

     

    Pois bem, tendo esclarecido este fato, vamos discutir a relação de performance, como sabemos no SQL Server como em todos os bancos ele precisa receber uma query->analisar->compilar, sendo assim conforme essa query vai se alterando dinamicamente, ele entende como uma nova query e faz todo o processo novamente.

     

    A principal diferença é a maneira que solicitamos que ele execute isto, existe o comando EXEC e a SP sp_executesql, a primeira alternativa realiza a execução e não se preocupa em mantar o plano de execução no Cache, já a segunda opção executa a query e tenta mantê-la no Cache afim de minimizar o uso desnecessário do processador compilando queries e afim de tornar a sua execução mais rápida, pois não precisa montar um novo plano de execução para esta.

     

    Sendo assim, sempre que for necessário executar queries de maneira dinâmica é aconselhável que você utilize o comando sp_executesql, você pode buscar mais informações deste no Books Online.

     

    No SQL Server 2005, esse processo foi minimizado pois ele realiza uma compilação parcial de stored procedures ou seja ele compila e monta o plano somente onde realmente foi alterado, economizando assim o tempo de processamento.

     

    Bom, espero ter esclarecido sua dúvida.

     

    Abraços,

    segunda-feira, 3 de março de 2008 16:25