Pergunta

Estou tentando otimizar algumas consultas SQL horrendamente complicadas, porque leva muito tempo para terminar.

Nas minhas consultas, criei dinamicamente as instruções SQL com muitas das mesmas funções, então criei uma tabela temporária em que cada função é chamada apenas uma vez em vez de muitas, muitas vezes - isso cortou meu tempo de execução em 3/4.

Então, minha pergunta é: posso esperar ver muita diferença, se digamos, 1.000 cálculos datediff são reduzidos a 100?

Editar: a consulta se parece com a seguinte:

SELECT DISTINCT M.MID, M.RE FROM #TEMP INNER JOIN M ON #TEMP.MID=M.MID 
WHERE ( #TEMP.Property1=1 ) AND 
DATEDIFF( year, M.DOB, @date2 ) >= 15  AND  DATEDIFF( year, M.DOB, @date2 ) <= 17 

onde estes estão sendo gerados dinamicamente como strings (montados em bits e peças) e depois executados para que vários parâmetros possam ser alterados ao longo de cada iteração - principalmente as últimas linhas, contendo todos os tipos de consultas datediff.

Existem cerca de 420 consultas como essa, onde esses datatediffs estão sendo calculados assim. Eu sei que posso puxá -los com facilidade de uma tabela de temperatura (1.000 datatediffs se tornam 50) - mas vale a pena, fará alguma diferença em segundos? Espero uma melhoria melhor do que nos décimos de segundos.

Foi útil?

Solução

Depende exatamente do que você está fazendo para ser honesto quanto à extensão do desempenho do desempenho.

Por exemplo, se você estiver usando o datediff (ou mesmo qualquer outra função) dentro de uma cláusula WHERE, isso será uma causa de desempenho mais pior, pois impedirá que um índice seja usado nessa coluna.

por exemplo, exemplo básico, encontrando todos os registros em 2009

WHERE DATEDIFF(yyyy, DateColumn, '2009-01-01') = 0

não faria bom uso de um índice no DataColumn. Enquanto uma solução melhor, fornecendo o uso ideal do índice seria:

WHERE DateColumn >= '2009-01-01' AND DateColumn < '2010-01-01'

EU recentemente blogou Sobre a diferença que isso faz (com comparações de estatísticas de desempenho/plano de execução), se você estiver interessado.

Isso seria mais caro do que o retorno do datediff como uma coluna no ResultSet.

Eu começaria identificando as consultas individuais que estão levando mais tempo. Verifique os planos de execução para ver onde está o problema e sintoniza a partir daí.

Editar:Com base na consulta de exemplo que você forneceu, aqui está uma abordagem que você pode tentar remover o uso do datediff na cláusula WHERE. Exemplo básico para encontrar todos que tinham 10 anos em uma determinada data - eu acho A matemática está certa, mas você entendeu de qualquer maneira! Dei um teste rápido e parece bom. Deve ser fácil o suficiente para se adaptar ao seu cenário. Se você deseja encontrar pessoas entre (por exemplo, 15 e 17 anos em uma determinada data, isso também é possível com essa abordagem.

-- Assuming @Date2 is set to the date at which you want to calculate someone's age 
DECLARE @AgeAtDate INTEGER
SET @AgeAtDate = 10  

DECLARE @BornFrom DATETIME
DECLARE @BornUntil DATETIME
SELECT @BornFrom = DATEADD(yyyy, -(@AgeAtDate + 1), @Date2)
SELECT @BornUntil = DATEADD(yyyy, -@AgeAtDate , @Date2)

SELECT DOB
FROM YourTable
WHERE DOB > @BornFrom AND DOB <= @BornUntil

Uma nota importante a acrescentar é para caculações de idade do DOB, essa abordagem é mais precisa. Sua implementação atual leva em consideração apenas o ano de nascimento, não o dia real (por exemplo, alguém nascido em 1º de dezembro de 2009 mostraria como um ano de 1 ano em 1º de janeiro de 2010, quando não é 1 até 1º de dezembro de 2010).

Espero que isto ajude.

Outras dicas

O datediff é bastante eficiente em comparação com outros métodos de manuseio de valores de dateTime, como strings. (Veja isso tão responde).

Nesse caso, parece que você está passando por cima e sobre os mesmos dados, o que provavelmente é mais caro do que usar uma tabela temporária. Por exemplo, as estatísticas serão geradas.

Uma coisa que você pode fazer para melhorar o desempenho pode ser colocar um índice na tabela de temperatura no meio.

Verifique seu plano de execução para ver se isso ajuda (pode depender do número de linhas na tabela Temp).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top