none
consulta com lentidão utilizando variáveis RRS feed

  • Pergunta

  • Boa tarde.

    Estou tentando realizar uma consulta simples a where baseado em 2 condições. Uma delas é a data...quando a hora está dentro de uma variável, a consulta demora muito tempo, já quando eu coloco as data manualmente,a consulta é realziada em 2 segundos.Por favor,alguémsabe o que poderia ser??

    Tentei como datediff(pois quero pegar de um dia especifico,mas também demora

    Consulta rápida:

    select 
        count (cHashEqpmtFixo) as TOTAL
    from mcent..tb_sessao_login_hist (nolock)
    where
    (cHashEqpmtFixo IS NOT NULL )
    and cd_data between '2012-03-27 00:00:00.000' and '2012-03-27 23:59:59.000'

    Consulta lenta:

    declare

      @dia varchar (10)
      ,@dtinicio varchar (24)
      ,@dtfinal varchar (24)

    Select @dia = '2012-03-27'
     
     
    Select  @dtinicio = @dia + ' 00:00:00.000'
       ,@dtfinal = @dia + ' 23:59:59.000'

    select 
      count (cHashEqpmtFixo) as TOTAL
    from mcent..tb_sessao_login_hist (nolock)
    where
    (cHashEqpmtFixo IS NOT NULL )
    and cd_data between  @dtinicio and @dtfinal

    sexta-feira, 30 de março de 2012 15:41

Respostas

  • Boa tarde Guimerz,

    Essa é situação conhecida como "parameter sniffing". Essa situação ocorre pelo fato de o otimizador de quey desconhecer o "possível" valor de sua variável. Sendo assim, ele nao consegue otimizar sua consulta. Uma saida para essa situacao é o uso do option "OPTIMIZE FOR". Nele vc pode especificar um "possivel" valor, para que quando o otimizador percorrer a consulta ele usará esse valor como parametro. O valor informado no OPTIMIZE FOR não interfere no resultado da sua consulta. Ele é usado somente para fim de otimização mesmo.  Ex:

    set @data = '2012-03-30'
    select * from table where cd_data = @data
    OPTION (OPTIMIZE FOR(@data='2012-01-01'))
    

    Atenciosamente,
    Rafael Melo

    • Marcado como Resposta Guimerz sexta-feira, 30 de março de 2012 19:48
    sexta-feira, 30 de março de 2012 18:40

Todas as Respostas

  • Olá boa tarde.

    Tente declarar a variável do tipo date ou datetime e coloque da seguinte forma:

    declare @data date

    set @data = '2012-03-27'

    select * from table where cd_data = @data

    Abs.


    Eduardo Gomes - http://www.h1solucoes.com.br - Twitter: @edugp_sp

    sexta-feira, 30 de março de 2012 16:00
  • Usando datetime:

    declare @data1 datetime, @data2 datetime

    set @data1 = '20120327 00:00:00'

    set @data2 = '20120327 23:59:59'

    select * from table where cd_data between @data1 and @data2

    Abs.


    Eduardo Gomes - http://www.h1solucoes.com.br - Twitter: @edugp_sp

    sexta-feira, 30 de março de 2012 16:01
  • Oi Eduardo,

    Obrigado pela ajuda, aindei refazendo os testes e vi que o comportamento é o mesmo quando utilizo outra data...

    Como sou leigo no assunto (posso até estar falando besteira) não sei se o SQL guarda algumas informações para melhorar a perfomance das consultas, por isso ela foi rápida com o dia 27, mas em outros dias, o comportamento foi o mesmo, lento.

    Desculpe pelo incomodo.

    Abs.

    Guilherme

    sexta-feira, 30 de março de 2012 17:40
  • Guilherme, boa tarde.

    O SQL cria estatísticas de querys executadas e trabalha com cache para executar query´s repetidas. Desta forma a mesma consulta executada duas vezes, na segunda ela se torna mais rápida.

    Quanto a perfomance: Ainda está lento? Qual o volume de registros nesta tabela? Existe índice no campo que deseja filtrar?

    Abs.


    Eduardo Gomes - http://www.h1solucoes.com.br - Twitter: @edugp_sp

    sexta-feira, 30 de março de 2012 17:44
  • Este campo cHashEqpmtFixo também tem índice?

    Abs.


    Eduardo Gomes - http://www.h1solucoes.com.br - Twitter: @edugp_sp

    sexta-feira, 30 de março de 2012 17:45
  • Oi Eduardo,

    Ainda está lento e tem aproximadamente 200 milhoes de registros, mas é um servidor muito bom.

    o campo cHashEqpmtFixo está indexado sim.

    obrigado!


    Abs., Guilherme Bighetti - @guibighetti

    sexta-feira, 30 de março de 2012 18:23
  • O campo cD_data também tem índice?

    Verifique também se os índices estão fragmentados.

    Utilize o comando dbcc showcontig


    Eduardo Gomes - http://www.h1solucoes.com.br - Twitter: @edugp_sp


    sexta-feira, 30 de março de 2012 18:30
  • Boa tarde Guimerz,

    Essa é situação conhecida como "parameter sniffing". Essa situação ocorre pelo fato de o otimizador de quey desconhecer o "possível" valor de sua variável. Sendo assim, ele nao consegue otimizar sua consulta. Uma saida para essa situacao é o uso do option "OPTIMIZE FOR". Nele vc pode especificar um "possivel" valor, para que quando o otimizador percorrer a consulta ele usará esse valor como parametro. O valor informado no OPTIMIZE FOR não interfere no resultado da sua consulta. Ele é usado somente para fim de otimização mesmo.  Ex:

    set @data = '2012-03-30'
    select * from table where cd_data = @data
    OPTION (OPTIMIZE FOR(@data='2012-01-01'))
    

    Atenciosamente,
    Rafael Melo

    • Marcado como Resposta Guimerz sexta-feira, 30 de março de 2012 19:48
    sexta-feira, 30 de março de 2012 18:40
  • Oi Rafael S. Melo,

    Obrigado pela ajuda também.

    O comando funcionou muito bem, mágico!

    Muito obrigado.

    podemos encerrar.


    Guilherme Bighetti - @guibighetti

    sexta-feira, 30 de março de 2012 19:48