none
Dúvidas quanto ao Plano de execução RRS feed

  • Pergunta

  • Boa tarde pessoal,

     

    Eu estou rodando uma proc meio chatinha, notei uma lentidão acima do normal, bem, olhei o plano de execução e vi um table scan e um clustered index scan. Esses dois eu ja acertei, só tenho index seek agora.

     

    Ok, mas algumas coisas aparecem no plano e eu não sei o que é:

    Table Spool (Eager Spool) cost 30%

    Hash Match (Inner Join) cost 15%

     

    Nesta proc eu faço algumas inserções em tabelas temporárias, faço alguns joins tb.

     

    Outra coisa tenho um :

    Clustered Index Seek cost 40%

    Isso é normal ?

    quarta-feira, 20 de junho de 2007 17:21

Todas as Respostas

  •  

    Olá Rick,

     

    Uma pergunta, no seu WHERE, está utilizando algum "OR" ou "IN"?

     

    Em algumas situações é interessante fazer um UNION de duas consultas do que usar OR.

     

    Exemplo que pode ter mau desempenho:

     

    SELECT NomeProduto FROM Produtos WHERE TipoProduto = 45 OR TipoProduto = 68

     

    Outra forma de obter o mesmo resultado mas pode obter melhor desempenho:

     

    SELECT NomeProduto FROM Produtos WHERE TipoProduto = 45

    UNION ALL

    SELECT NomeProduto FROM Produtos WHERE TipoProduto = 68

     

     

    Tente postar aqui pelo menos parte do seu código para termos analisar melhor.

     

     

    Abraço

    quarta-feira, 20 de junho de 2007 17:48
  • Não tenho numu "or" ou "in"

     

    Bom, o código é meio chatinho e possívelmente não é o ideal não fui eu quem o fez.

    Basicamente ele gera duas tabelas temporárias para emissão de relatório usando crystal.

    a parte de código que eu fiz é apenas os create index e drop index em uma das temporárias.

    Declare @tabela as char(25)

    Declare @instrucao as varchar(1500)

    Declare @ordem as varchar(200)

    -- Atribui o nome para a tabela temporaria

    Select @tabela = '_AVLVLR_' + replace(replace(replace(replace(Convert(varchar(40),getdate(),121),'-',''),':',''),' ',''),'.','')

     

    -- Criação da tabela temporaria que servirá de base para o relatorio

    Select -- Campos Chaves

    a.projeto_codigo,

    a.subprojeto_codigo,

    a.equipamento_codigo,

    a.avaliacao_codigo,

    -- Campos do Cabeçalho

    d.cliente_razao_social as Razao_Social,

    c.subprojeto_data_base as Data_Base,

    c.subprojeto_descricao as Unidade,

    -- Campos do Detalhe

    Convert(Varchar(30), AME.dbo.FU_AVL_concatena(' / ',ltrim(rtrim(isnull(a.avaliacao_patrimonio,''))), ltrim(rtrim(isnull(a.avaliacao_incorp,''))))) as num_bem,

    a.avaliacao_ficha as ficha,

    a.avaliacao_equipamento_descricao as Descricao_Bem,

    a.equipamento_cotacao_data,

    Convert(numeric(6,2),null) as vida_util,

    Convert(numeric(6,2),null) as vida_util_perc,

    Convert(numeric(18,2),null) as valor_reposicao,

    Convert(numeric(18,2),null) as valor_mercado,

    Convert(numeric(18,2),null) as valor_maximo_seguravel,

    Convert(numeric(18,2),null) as valor_danos_eletricos,

    a.localidade_equipamento_codigo as localidade_equipamento_codigo,

    Convert(varchar(25), Null) as localidade_equipamento_sigla,

    Convert(varchar(100), Null) as localidade_equipamento_descricao,

    a.planta_seguro_codigo as planta_seguro_codigo,

    Convert(varchar(15), Null) as planta_seguro_numero,

    Convert(varchar(100), Null) as planta_seguro_descricao,

    a.centro_custo_codigo as centro_custo_codigo,

    Convert(varchar(15), Null) as centro_custo_numero,

    Convert(varchar(100), Null) as centro_custo_descricao,

    a.conta_contabil_codigo as conta_contabil_codigo,

    Convert(varchar(15), Null) as conta_contabil_conta,

    Convert(varchar(100), Null) as conta_contabil_descricao,

    a.avaliacao_nota,

    a.avaliacao_ano_aparente,

    a.avaliacao_quantidade,

    Convert(tinyint, Null) as meio_codigo,

    Convert(char(2), Null) as meio_sigla,

    Convert(smallint, Null) as classe_codigo,

    Convert(char(3), Null) as classe_sigla,

    Convert(numeric(5,2), Null) as classe_danos_eletricos,

    c.subprojeto_descricao,

    a.segmento_sigla

    Into

    #rel_avaliacao_analitico

    From

    avaliacao a,

    projeto b,

    subprojeto c,

    cliente d,

    equipamento_cotacao f

    Where

    a.projeto_codigo = 1262 AND

    a.subprojeto_codigo = 1 AND

    b.projeto_codigo = a.projeto_codigo AND

    c.projeto_codigo = a.projeto_codigo AND

    c.subprojeto_codigo = a.subprojeto_codigo AND

    d.cliente_codigo = b.cliente_codigo AND

    f.equipamento_codigo = a.equipamento_codigo AND

    f.projeto_codigo=1262 AND

    f.subprojeto_codigo=1

    -- Identifica os campos com as tabelas correspondentes

    -- Conta_contabil, Centro_Custo, Planta_seguro e Localidade_equipamento

    CREATE clustered INDEX tmprel001 on #rel_avaliacao_analitico (projeto_codigo asc,subprojeto_codigo asc,localidade_equipamento_codigo asc)

    Update #rel_avaliacao_analitico

    Set localidade_equipamento_sigla = b.localidade_equipamento_sigla,

    localidade_equipamento_descricao = b.localidade_equipamento_descricao

    From #rel_avaliacao_analitico a,

    localidade_equipamento b

    Where a.projeto_codigo = b.projeto_codigo AND

    a.subprojeto_codigo = b.subprojeto_codigo AND

    a.localidade_equipamento_codigo = b.localidade_equipamento_codigo

    drop INDEX #rel_avaliacao_analitico.tmprel001

    CREATE clustered INDEX tmprel001 on #rel_avaliacao_analitico (projeto_codigo asc,subprojeto_codigo asc,planta_seguro_codigo asc)

    Update #rel_avaliacao_analitico

    Set planta_seguro_numero = b.planta_seguro_numero,

    planta_seguro_descricao = b.planta_seguro_descricao

    From #rel_avaliacao_analitico a,

    planta_seguro b

    Where a.projeto_codigo = b.projeto_codigo AND

    a.subprojeto_codigo = b.subprojeto_codigo AND

    a.planta_seguro_codigo = b.planta_seguro_codigo

    drop INDEX #rel_avaliacao_analitico.tmprel001

    CREATE clustered INDEX tmprel001 on #rel_avaliacao_analitico (projeto_codigo asc,subprojeto_codigo asc,centro_custo_codigo asc)

    Update #rel_avaliacao_analitico

    Set centro_custo_numero = b.centro_custo_numero,

    centro_custo_descricao = b.centro_custo_descricao

    From #rel_avaliacao_analitico a,

    centro_custo b

    Where a.projeto_codigo = b.projeto_codigo AND

    a.subprojeto_codigo = b.subprojeto_codigo AND

    a.centro_custo_codigo = b.centro_custo_codigo

    drop INDEX #rel_avaliacao_analitico.tmprel001

    CREATE clustered INDEX tmprel001 on #rel_avaliacao_analitico (projeto_codigo asc,subprojeto_codigo asc,conta_contabil_codigo asc)

    Update #rel_avaliacao_analitico

    Set conta_contabil_conta = b.conta_contabil_conta,

    conta_contabil_descricao = b.conta_contabil_descricao

    From #rel_avaliacao_analitico a,

    conta_contabil b

    Where a.projeto_codigo = b.projeto_codigo AND

    a.subprojeto_codigo = b.subprojeto_codigo AND

    a.conta_contabil_codigo = b.conta_contabil_codigo

    drop INDEX #rel_avaliacao_analitico.tmprel001

    -- Cria a tabela para receber os calculos

    Execute dbo.SP_AVL_avaliacao_criatmp @tabela

    -- Coloca os dados necessarios para calculos na temporária

    Select @instrucao =

    ' Insert ' + @tabela + ' (

    projeto_codigo,

    subprojeto_codigo,

    equipamento_codigo,

    avaliacao_codigo,

    equipamento_cotacao_data,

    avaliacao_nota,

    avaliacao_ano_aparente,

    avaliacao_quantidade )

    Select projeto_codigo,

    subprojeto_codigo,

    equipamento_codigo,

    avaliacao_codigo,

    equipamento_cotacao_data,

    avaliacao_nota,

    avaliacao_ano_aparente,

    avaliacao_quantidade

    From avaliacao

    where projeto_codigo = ' + convert(char(4),1262) + 'and

    subprojeto_codigo = ' + convert(char(4),1)

    Execute(@instrucao)

    -- Calcula os valores da tabela temporária

    Execute dbo.SP_AVL_Avaliacao_Valores @tabela

    -- Realiza Update na tabela do relatório com os valores calculados

    CREATE clustered INDEX tmprel001 on #rel_avaliacao_analitico (projeto_codigo asc,equipamento_codigo asc,subprojeto_codigo asc)

    Select @instrucao =

    ' Update #rel_avaliacao_analitico

    Set meio_codigo = b.meio_codigo,

    classe_codigo = b.classe_codigo,

    classe_danos_eletricos = b.danos_eletricos,

    vida_util = b.vida_util,

    vida_util_perc = b.vida_util_perc,

    valor_reposicao = b.valor_reposicao,

    valor_mercado = b.valor_mercado,

    valor_maximo_seguravel = b.valor_maximo_seguravel,

    valor_danos_eletricos = b.valor_danos_eletricos

    From #rel_avaliacao_analitico a, ' + @tabela + ' b' +

    ' Where a.avaliacao_codigo = b.avaliacao_codigo and

    a.projeto_codigo = b.projeto_codigo and

    a.equipamento_codigo = b.equipamento_codigo and

    a.subprojeto_codigo = b.subprojeto_codigo '

    Execute(@instrucao)

    drop INDEX #rel_avaliacao_analitico.tmprel001

    -- Apaga a tabela temporária de calculos , fiscamente do banco

    Select @instrucao = 'Drop table ' + @tabela

    Execute (@Instrucao)

    -- Acerta as siglas do MEIO e da Classe

    CREATE clustered INDEX tmprel001 on #rel_avaliacao_analitico (meio_codigo asc)

    Update #rel_avaliacao_analitico

    Set meio_sigla = b.meio_sigla

    From #rel_avaliacao_analitico a,

    meio b

    Where a.meio_codigo = b.meio_codigo

    drop INDEX #rel_avaliacao_analitico.tmprel001

    CREATE clustered INDEX tmprel001 on #rel_avaliacao_analitico (classe_codigo asc)

    Update #rel_avaliacao_analitico

    Set classe_sigla = b.classe_sigla

    From #rel_avaliacao_analitico a,

    classe b

    Where a.classe_codigo = b.classe_codigo

    drop INDEX #rel_avaliacao_analitico.tmprel001

    -- Acerta a ordem de saída da infromação

    CREATE CLUSTERED INDEX tmprel on #rel_avaliacao_analitico (Projeto_Codigo,SubProjeto_Codigo,segmento_sigla)

    If 1 = 1

    Begin

    CREATE INDEX tmprel2 on #rel_avaliacao_analitico (descricao_bem ASC, valor_reposicao DESC)

    Select @ordem = 'Order by descricao_bem ASC , valor_reposicao DESC '

    End

    Else If 1 = 2

    Begin

    CREATE INDEX tmprel on #rel_avaliacao_analitico (valor_reposicao DESC, descricao_bem ASC)

    Select @ordem = 'Order by valor_reposicao DESC, descricao_bem ASC'

    End

    Set nocount off

    -- Seleciona os campos para o Crystal Reports

    Select @instrucao = '

    Select r.projeto_codigo,

    Convert(char(3),replicate(''0'', 3 - Len(r.subprojeto_codigo)) + Convert(varchar(3), r.subprojeto_codigo)) as subprojeto_codigo,

    subprojeto_descricao,

    equipamento_codigo,

    avaliacao_codigo,

    Razao_Social,

    Data_Base,

    Unidade,

    num_bem,

    ficha,

    Descricao_Bem,

    equipamento_cotacao_data,

    vida_util,

    vida_util_perc,

    valor_reposicao,

    valor_mercado,

    valor_maximo_seguravel,

    valor_danos_eletricos,

    localidade_equipamento_codigo,

    localidade_equipamento_sigla,

    localidade_equipamento_descricao,

    planta_seguro_codigo,

    planta_seguro_numero,

    planta_seguro_descricao,

    centro_custo_codigo,

    centro_custo_numero,

    centro_custo_descricao,

    conta_contabil_codigo,

    conta_contabil_conta,

    conta_contabil_descricao,

    avaliacao_nota,

    avaliacao_ano_aparente,

    avaliacao_quantidade,

    meio_codigo,

    meio_sigla,

    classe_codigo,

    classe_sigla,

    classe_danos_eletricos,

    r.segmento_sigla,

    s.segmento_acessorio,

    s.segmento_montagem,

    s.segmento_admengproj

    --Into lixo5

    From

    #rel_avaliacao_analitico r inner join segmentos s on r.Projeto_Codigo=s.Projeto_Codigo

    and r.subprojeto_codigo=s.SubProjeto_Codigo

    and r.segmento_sigla=s.segmento_sigla '

    + @ordem

    Execute(@instrucao)

    quarta-feira, 20 de junho de 2007 18:05
  •  

    Rick,

     

    Vendo o código, realmente está um tanto complicado de analisar qual o possível problema. O código deveria estar rápido para execução. O que pode estar fazendo com que demore é a quantidade de dados.

     

    Quanto de daos você tem hoje??

     

     

    Abraço

    quarta-feira, 20 de junho de 2007 19:16
  • 50.000 registro, até não é muito.

     

    Alguns problemas que eu sei que não vai ter como acertar é que por exemplo o relatório retorna TODOS os registro (50mil), mas até aí tudo bem, o problema está sendo 50% de processamento. Sem contar que este script chama outro script que faz zilhões de update em tabelas temporárias (como eu disse não fui eu que fiz hehehe).

    Bom vamos ao que pode me dar uma luz no fim do túnel:

     

    Que diabos é esse negócio de Table Spooling ?

    E esse tal de Hash Join ?

    E o fato do meu clustered index estar comendo 40% do meu processamento, é normal, pode ocorrer?

     

    Se você tiver algum link pra eu ler sobre esses trecos aí fico grato, pois além desses queria dar uma lida sobre os bookmarks, embora estejam comendo 0% do meu processamento.

     

    vlws.

    quarta-feira, 20 de junho de 2007 19:30
  •  

    Rick,

     

    Nesse link tem algumas informações bem interessantes sobre o plano de execução:

    http://www.sql-server-performance.com/query_execution_plan_analysis.asp

     

    Sobre o Table Spool, ele ocorre quando o SQL tem que fazer a criação de uma área temporária dentro da TEMPDB para trabalhar com os dados. Para resolver isso, em geral teria que verificar a possibilidade de modificar a consulta, mas, tente analizar ela dentro do Index Tuning Wizard (Se for sql 2000) ou no Database Tuning Advisor (SQL 2005), pode ser que recomende algum índice para melhorar o desempenho.

     

     

    Abraço

    quarta-feira, 20 de junho de 2007 19:58
  • Bom dia Rick

     

    Um outro problema que vejo é a criação dos índices nas tabelas temporárias, o SQL Server gasta tempo criando, mantendo e excluíndo o índice, não seria mais interessante incluir os dados baseados em um ORDER BY ? Creio que sim, acho que com essa simples alteração você pode ganhar um tempo precioso.

     

     

     

     

     

     

    Espero ter ajudado

    quinta-feira, 21 de junho de 2007 10:57
  • @Alexandre,

     

    Obrigado pelo link , quanto ao uso do tunning, ja tentei usar, o problema mesmo está na criação e updates em tabelas temporárias, vou tentar refazer a rotina sem usar temporárias.

     

    @Anderson,

     

    A inclusão de indices na temporária foi uma tentativa de melhora em zilhões de inserts e updates, note que essa rotina chama uma outra que também tem zilhões de updates, ta osso isso.

     

    Como disse acima, vou tentar refazer a rotina sem usar temporárias.

    quinta-feira, 21 de junho de 2007 11:10
  • segue alguumas instrucoes que foram a recompilacao.

     

     comandos set dentro de proc

     criacao de tabelas temporarias

     execucao usando exec ('' )

     

     criacao de objetos de banco como indices, etc.

     

     se sua proc tem algum desses procedimentos era sera recompilada todas as vezes que for executada.

     

    Abs

     

    quinta-feira, 21 de junho de 2007 12:05
  • Marcelo,

     

    Eu mudei algumas coisas, mas não consegui fugir da criação de tabelas temporárias.

    Quanto a instruções "set" eu posso substituir por "select", seria melhor ou da na mesma ?

    Quanto a criação de indices posso remover pra ver como fica.

    Eu basicamente mudei um pouco o primeiro select, que estava usando "tabela1,tabela2,tabela3" que pelo que sei não é mais suportado no SQL 2005, com isto consegui retirar 4 updates que ocorriam no meio da proc, então faço o select dos dados que preciso (acho que isto deve melhorar o desempenho)

    Segue como está a proc:

    Note que esta proc executa outras duas, uma apenas cria uma tabela (não temporária), a outra faz uma série de updates nesta tabela que foi criada.

     

     

    Code Snippet

    Declare @tabela as char(25)

    Declare @instrucao as varchar(1500)

    Declare @ordem as varchar(200)

    -- Atribui o nome para a tabela temporaria

    Select @tabela = '_AVLVLR_' + replace(replace(replace(replace(Convert(varchar(40),getdate(),121),'-',''),':',''),' ',''),'.','')

     

    -- Criação da tabela temporaria que servirá de base para o relatorio

    Select -- Campos Chaves

    a.projeto_codigo,

    a.subprojeto_codigo,

    a.equipamento_codigo,

    a.avaliacao_codigo,

    -- Campos do Cabeçalho

    d.cliente_razao_social as Razao_Social,

    c.subprojeto_data_base as Data_Base,

    c.subprojeto_descricao as Unidade,

    -- Campos do Detalhe

    Convert(Varchar(30), AME.dbo.FU_AVL_concatena(' / ',ltrim(rtrim(isnull(a.avaliacao_patrimonio,''))), ltrim(rtrim(isnull(a.avaliacao_incorp,''))))) as num_bem,

    a.avaliacao_ficha as ficha,

    a.avaliacao_equipamento_descricao as Descricao_Bem,

    a.equipamento_cotacao_data,

    Convert(numeric(6,2),null) as vida_util,

    Convert(numeric(6,2),null) as vida_util_perc,

    Convert(numeric(18,2),null) as valor_reposicao,

    Convert(numeric(18,2),null) as valor_mercado,

    Convert(numeric(18,2),null) as valor_maximo_seguravel,

    Convert(numeric(18,2),null) as valor_danos_eletricos,

    a.localidade_equipamento_codigo as localidade_equipamento_codigo,

    g.localidade_equipamento_sigla as localidade_equipamento_sigla,

    g.localidade_equipamento_descricao as localidade_equipamento_descricao,

    a.planta_seguro_codigo as planta_seguro_codigo,

    h.planta_seguro_numero as planta_seguro_numero,

    h.planta_seguro_descricao as planta_seguro_descricao,

    a.centro_custo_codigo as centro_custo_codigo,

    i.centro_custo_numero as centro_custo_numero,

    i.centro_custo_descricao as centro_custo_descricao,

    a.conta_contabil_codigo as conta_contabil_codigo,

    j.conta_contabil_conta as conta_contabil_conta,

    j.conta_contabil_descricao as conta_contabil_descricao,

    a.avaliacao_nota,

    a.avaliacao_ano_aparente,

    a.avaliacao_quantidade,

    Convert(tinyint, Null) as meio_codigo,

    Convert(char(2), Null) as meio_sigla,

    Convert(smallint, Null) as classe_codigo,

    Convert(char(3), Null) as classe_sigla,

    Convert(numeric(5,2), Null) as classe_danos_eletricos,

    c.subprojeto_descricao,

    a.segmento_sigla,

    s.segmento_acessorio,

    s.segmento_montagem,

    s.segmento_admengproj

    Into

    #rel_avaliacao_analitico

    From

    ((((((((avaliacao a

    inner join projeto b on b.projeto_codigo = a.projeto_codigo)

    inner join subprojeto c on c.projeto_codigo = a.projeto_codigo and c.subprojeto_codigo = a.subprojeto_codigo)

    inner join cliente d on d.cliente_codigo = b.cliente_codigo)

    inner join equipamento_cotacao f on f.equipamento_codigo = a.equipamento_codigo)

    inner join localidade_equipamento g on g.localidade_equipamento_codigo = a.localidade_equipamento_codigo)

    left outer join planta_seguro h on (h.planta_seguro_codigo=a.planta_seguro_codigo and h.projeto_codigo=a.projeto_codigo and h.subprojeto_codigo=a.subprojeto_codigo))

    inner join centro_custo i on i.centro_custo_codigo = a.centro_custo_codigo)

    inner join conta_contabil j on j.conta_contabil_codigo = a.conta_contabil_codigo)

    inner join segmentos s on s.segmento_sigla=a.segmento_sigla

    Where

    ( a.projeto_codigo = @projeto_codigo and a.subprojeto_codigo = @subprojeto_codigo) AND

    ( b.projeto_codigo = @projeto_codigo) AND

    ( c.projeto_codigo = @projeto_codigo and c.subprojeto_codigo = @subprojeto_codigo) AND

    ( f.projeto_codigo = @projeto_codigo and f.subprojeto_codigo = @subprojeto_codigo) AND

    ( g.projeto_codigo = @projeto_codigo and g.subprojeto_codigo = @subprojeto_codigo) AND

    ( i.projeto_codigo = @projeto_codigo and i.subprojeto_codigo = @subprojeto_codigo) AND

    ( j.projeto_codigo = @projeto_codigo and j.subprojeto_codigo = @subprojeto_codigo) AND

    ( s.projeto_codigo = @projeto_codigo and s.subprojeto_codigo = @subprojeto_codigo)

    -- Cria a tabela para receber os calculos

    Execute dbo.SP_AVL_avaliacao_criatmp @tabela

    -- Coloca os dados necessarios para calculos na temporária

    Select @instrucao =

    ' Insert ' + @tabela + ' (

    projeto_codigo,

    subprojeto_codigo,

    equipamento_codigo,

    avaliacao_codigo,

    equipamento_cotacao_data,

    avaliacao_nota,

    avaliacao_ano_aparente,

    avaliacao_quantidade )

    Select projeto_codigo,

    subprojeto_codigo,

    equipamento_codigo,

    avaliacao_codigo,

    equipamento_cotacao_data,

    avaliacao_nota,

    avaliacao_ano_aparente,

    avaliacao_quantidade

    From avaliacao

    where projeto_codigo = ' + convert(char(4),@projeto_codigo) + 'and

    subprojeto_codigo = ' + convert(char(4),@subprojeto_codigo)

    Execute(@instrucao)

    -- Calcula os valores da tabela temporária

    Execute dbo.SP_AVL_Avaliacao_Valores @tabela

    -- Realiza Update na tabela do relatório com os valores calculados

    CREATE clustered INDEX tmprel001 on #rel_avaliacao_analitico (projeto_codigo asc,equipamento_codigo asc,subprojeto_codigo asc)

    Select @instrucao =

    ' Update #rel_avaliacao_analitico

    Set meio_codigo = b.meio_codigo,

    classe_codigo = b.classe_codigo,

    classe_danos_eletricos = b.danos_eletricos,

    vida_util = b.vida_util,

    vida_util_perc = b.vida_util_perc,

    valor_reposicao = b.valor_reposicao,

    valor_mercado = b.valor_mercado,

    valor_maximo_seguravel = b.valor_maximo_seguravel,

    valor_danos_eletricos = b.valor_danos_eletricos

    From #rel_avaliacao_analitico a, ' + @tabela + ' b' +

    ' Where a.avaliacao_codigo = b.avaliacao_codigo and

    a.projeto_codigo = b.projeto_codigo and

    a.equipamento_codigo = b.equipamento_codigo and

    a.subprojeto_codigo = b.subprojeto_codigo '

    Execute(@instrucao)

    drop INDEX #rel_avaliacao_analitico.tmprel001

    -- Apaga a tabela temporária de calculos , fiscamente do banco

    Select @instrucao = 'Drop table ' + @tabela

    Execute (@Instrucao)

    -- Acerta as siglas do MEIO e da Classe

    CREATE clustered INDEX tmprel001 on #rel_avaliacao_analitico (meio_codigo asc)

    Update #rel_avaliacao_analitico

    Set meio_sigla = b.meio_sigla

    From #rel_avaliacao_analitico a,

    meio b

    Where a.meio_codigo = b.meio_codigo

    drop INDEX #rel_avaliacao_analitico.tmprel001

    CREATE clustered INDEX tmprel001 on #rel_avaliacao_analitico (classe_codigo asc)

    Update #rel_avaliacao_analitico

    Set classe_sigla = b.classe_sigla

    From #rel_avaliacao_analitico a,

    classe b

    Where a.classe_codigo = b.classe_codigo

    drop INDEX #rel_avaliacao_analitico.tmprel001

    -- Acerta a ordem de saída da infromação

    If @ordem_codigo = 1

    Begin

    CREATE INDEX tmprel2 on #rel_avaliacao_analitico (descricao_bem ASC, valor_reposicao DESC)

    Select @ordem = 'Order by descricao_bem ASC , valor_reposicao DESC '

    End

    Else If @ordem_codigo = 2

    Begin

    CREATE INDEX tmprel on #rel_avaliacao_analitico (valor_reposicao DESC, descricao_bem ASC)

    Select @ordem = 'Order by valor_reposicao DESC, descricao_bem ASC'

    End

    Set nocount off

    -- Seleciona os campos para o Crystal Reports

    Select @instrucao = '

    Select r.projeto_codigo,

    Convert(char(3),replicate(''0'', 3 - Len(r.subprojeto_codigo)) + Convert(varchar(3), r.subprojeto_codigo)) as subprojeto_codigo,

    subprojeto_descricao,

    equipamento_codigo,

    avaliacao_codigo,

    Razao_Social,

    Data_Base,

    Unidade,

    num_bem,

    ficha,

    Descricao_Bem,

    equipamento_cotacao_data,

    vida_util,

    vida_util_perc,

    valor_reposicao,

    valor_mercado,

    valor_maximo_seguravel,

    valor_danos_eletricos,

    localidade_equipamento_codigo,

    localidade_equipamento_sigla,

    localidade_equipamento_descricao,

    planta_seguro_codigo,

    planta_seguro_numero,

    planta_seguro_descricao,

    centro_custo_codigo,

    centro_custo_numero,

    centro_custo_descricao,

    conta_contabil_codigo,

    conta_contabil_conta,

    conta_contabil_descricao,

    avaliacao_nota,

    avaliacao_ano_aparente,

    avaliacao_quantidade,

    meio_codigo,

    meio_sigla,

    classe_codigo,

    classe_sigla,

    classe_danos_eletricos,

    segmento_sigla,

    segmento_acessorio,

    segmento_montagem,

    segmento_admengproj

    From

    #rel_avaliacao_analitico r '

    + @ordem

    Execute(@instrucao)

     

    quinta-feira, 21 de junho de 2007 14:24
  •  

     

    nas instrucoes concatenadas altere o exec por sp_executesql essa proc mantem planos de execucao, e ao invez de usar tabela temporaria use uma variavel table ( ira recompilar tambem ) mais vc. nao vai perder tempo indo ate o cache procurar a rotina gerada. ( cache miss )

     

     

    Abs.

    quinta-feira, 21 de junho de 2007 18:02
  • No caso so sp_executesql, não consegui entender é meio confuso aquilo, por exemplo vi no BOL um exemplo:

    Code Snippet
    DECLARE @IntVariable int;
    DECLARE @SQLString nvarchar(500);
    DECLARE @ParmDefinition nvarchar(500);
    DECLARE @max_title varchar(30);
    SET @IntVariable = 197;
    SET @SQLString = N'SELECT @max_titleOUT = max(Title)
        FROM AdventureWorks.HumanResources.Employee
        WHERE ManagerID = @level';
    SET @ParmDefinition = N'@level tinyint, @max_titleOUT varchar(30) OUTPUT';
    EXECUTE sp_executesql @SQLString, @ParmDefinition, @level = @IntVariable, @max_titleOUT=@max_title OUTPUT;
    SELECT @max_title;

     

     Vendo isso fiquei com algumas dúvidas:

    - O "N" na frente significa o que?

    - na linha onde seta o ParmDefinition, tem umas variáveis, elas estão sendo declaradas ali mesmo ?

    - para retoranar por exemplo 20 campos de uma consulta, eu teria que declarar 20 variáveis ali no ParmDefinition ? 

     

    O lance sobre usar a variável table ao invés de criar uma tabela tamporária eu não entendi.

    quinta-feira, 21 de junho de 2007 20:02
  •  

    Rick,

     

    Sobre o sp_executesql, recomendo você dar uma lida nessa matéria:

    http://www.sommarskog.se/dyn-search.html

     

    Bem explicado.

     

    Sobre o "N", é usado para identificar dados de caracter Unicode, no caso do NVarchar e NChar.

     

    A declaração de tabelas, você pode usar assim:

     

    DECLARE @NomeDaTabela TABLE (Campo1 INT IDENTITY (1,1), Campo2 VARCHAR (200) )

     

    É melhor que usar o CREATE TABLE #Nome......  Com este, o plano de execução será recompilado, gerando custo de processamento, no caso do DECLARE isso poderá não ocorrer.

     

     

    Abraço

    quinta-feira, 21 de junho de 2007 20:48
  • Fiz o lance de usar variavel table, deu certo e tals, mas to com um problema aqui, veja o código:

    Minha tabela:

    Code Snippet

    Declare @TmpAvaliacao Table

    (projeto_codigo smallint,

    sbuprojeto smallint

    etc,etc

     

    Erro ocorrem em: 

    Code Snippet

    Select @instrucao =

    'Update ' + @TmpAvaliacao +

    ' Set meio_codigo = b.meio_codigo,

    classe_codigo = b.classe_codigo,

    classe_danos_eletricos = b.danos_eletricos,

    vida_util = b.vida_util,

    vida_util_perc = b.vida_util_perc,

    valor_reposicao = b.valor_reposicao,

    valor_mercado = b.valor_mercado,

    valor_maximo_seguravel = b.valor_maximo_seguravel,

    valor_danos_eletricos = b.valor_danos_eletricos

    From ' + @TmpAvaliacao + ' a, ' + @tabela + ' b' +

    ' Where a.avaliacao_codigo = b.avaliacao_codigo and

    a.projeto_codigo = b.projeto_codigo and

    a.equipamento_codigo = b.equipamento_codigo and

    a.subprojeto_codigo = b.subprojeto_codigo '

    Execute (@instrucao)

     

    Tá dando um erro:

    Msg 137, Level 15, State 2, Procedure SP_AVL_REL_avaliacao_conferencia_eletropaulo, Line 276

    Must declare the variable '@TmpAvaliacao'.

     

     

    sexta-feira, 22 de junho de 2007 11:29