none
Consulta sql muito lenta em um select simples RRS feed

  • Pergunta

  • Bom dia a todos, estou com um problema um pouco chato por aqui. Tenho uma tabela bem simples com aproximadamente 100 colunas e um dos campos é do tipo datetime. Essa tabela não possui chave primária nem chave estrangeira. É uma tabela bem simples onde gravo registros no horário do servidor (getdate()). 

    data_hora |  colun1 | colun2 | colun3 | colun4 ... | colun100 

    Não são todas as colunas que possuem dados a principio, então há coluna que ficam como NULL. Porém no select eu busco apenas as colunas que possuem dados, mais ou menos assim: 

    * select top1 data_hora, colun1, colun2, colun9, colun10, colun12 ... from tabela order by data_hora desc

    Faço esse select para pegar os dados do último registro. Porém essa consulta demora cerca de 3 minutos para concluir, o que vejo como um tanto lenta pela simplicidade. Nesse select busco aproximadamente 30 colunas.

    Alguns dados importantes: 

    - Utilizado o banco de dados SQL Server 2014 Express 

    - O banco possui atualmente cerca de 1 milhão de registro, e são inseridos novos registros a cada 5 minutos. 

    - Meu servidor possui 8gb de ram e um processador pentium G2020.

    Verifiquei que muitos indicam a criação de índices, nesse caso seria em cima da coluna data_hora? 

    Há alguma forma de melhorar o desempenho dessa consulta?

    Edit: Na verdade esqueci de um detalhe, tenho uma coluna equipamento também, tenho 70 equipamentos, e para cada registro inserido coloco o numero do equipamento nessa coluna, e meu select na verdade fica dessa forma: 

    - * select top1 data_hora, equipamento, colun1, colun2, colun9, colun10, colun12 ... from tabela where equipamento = 1 order by data_hora desc

    quinta-feira, 13 de setembro de 2018 13:46

Respostas

Todas as Respostas

  • Willian,

    Quantas linhas essa consulta retorna? Se são muitas a consulta pode ser rápida, mas o retorno dos dados não, pela quantidade.

    Essa tabela possui um índice clustered?
    Você consegue postar aqui o plano de execução dessa consulta?


    Mariana Del Nero /* Se a resposta foi útil, não esqueça de marcá-la */

    quinta-feira, 13 de setembro de 2018 14:08
  • Essa consulta me retorna uma linha, apenas o última linha do equipamento em consulta. 

    Essa tabela não possui nenhum índice. 

    Desculpe, como estou iniciando nesse mundo de banco de dados, como eu faria para postar aqui  o plano de consuta? 

    Outra duvida, caso fosse criar um índice, seria em cima do campo data_hora, que uso no meu order by, ou seria no campo equipamento onde uso na minha clausula WHERE?

    quinta-feira, 13 de setembro de 2018 14:47
  • Você habilita a exibição do plano de execução com Ctrl + M. Ele vai ser exibido numa aba ao lado do seu result.

    Quanto ao índice, o clustered você precisa avaliar sua tabela porque ele é a ordem física da tabela. É como a tabela é gravada no disco.
    Então se colocar um campo que tem valores totalmente desordenados, vai sofrer com fragmentação dessa tabela.
    O ideal seria um campo numérico e auto incremental.

    Quanto a sua consulta, você pode criar um índice não clustered com base no seu where. Avalie se esse índice vai atender não só a sua consulta, mas a outras consultas ou se sua consulta será executada muitas vezes. 
    O que quero dizer é que não se deve criar um índice para satisfazer apenas uma consulta se essa não for muito importante e muito executada.

    E fique à vontade para perguntar. Todos nós estamos aqui para tentar ajudar mesmo e para sermos ajudados.


    Mariana Del Nero /* Se a resposta foi útil, não esqueça de marcá-la */

    quinta-feira, 13 de setembro de 2018 15:00
  • Deleted
    quinta-feira, 13 de setembro de 2018 17:32
  • Exatamente José Diz, os valores são inseridos de forma crescente conforme o campo data_hora, meu insert fica dessa forma: 

    - insert into tabela values (getdate(), num_equipamento, colun1, colun2, colun3), e assim por diante, na minha aplicação scada eu tenho um script para executar esse insert a cada 5 minutos. São 70 inserts, 1 para cada equipamento, ou seja a coluna equipamento sempre varia de 1 a 70. Para mostrar o último valor na minha tela (valor mais atual) eu faço esse select passando o numero do meu equipamento como clausula. 

     - select top1 data_hora, equipamento, colun1, colun2, colun9, colun10, colun12 ... from tabela where equipamento = @equipamento order by data_hora desc

    Meu campo data_hora é do tipo datetime. 

    quinta-feira, 13 de setembro de 2018 17:56
  • Deleted
    quinta-feira, 13 de setembro de 2018 19:38