Quando você tem uma consulta ou procedimento armazenado que precisa de ajuste de desempenho, quais são as primeiras coisas que você tenta?
sql
sql-server
database
performance
Terrapin
fonte
fonte
Respostas:
Aqui está a lista prática de coisas que sempre dou a alguém que me pergunta sobre otimização.
Usamos principalmente o Sybase, mas a maioria dos conselhos se aplica a todos.
O SQL Server, por exemplo, vem com uma série de bits de monitoramento / ajuste de desempenho, mas se você não tiver nada parecido (e talvez até o faça), considerarei o seguinte ...
99% dos problemas que eu vi são causados por colocar muitas tabelas em uma junção . A correção para isso é fazer metade da junção (com algumas das tabelas) e armazenar em cache os resultados em uma tabela temporária. Em seguida, faça o restante da consulta ingressando nessa tabela temporária.
Lista de verificação de otimização de consulta
#temp
As tabelas podem ter um desempenho muito melhor que as@table
variáveis com grandes volumes (milhares de linhas).fonte
fonte
Um pouco fora do tópico, mas se você tiver controle sobre esses problemas ...
Alto nível e Alto impacto.
fonte
CREATE INDEX
Verifique se há índices disponíveis para suas cláusulas
WHERE
eJOIN
. Isso agilizará bastante o acesso aos dados.Se o seu ambiente é um data mart ou armazém, os índices deverão ser abundantes para quase todas as consultas possíveis.
Em um ambiente transacional , o número de índices deve ser menor e suas definições mais estratégicas, para que a manutenção do índice não arraste recursos. (A manutenção do índice é quando as folhas de um índice devem ser alteradas para refletir uma alteração na tabela subjacente, como acontece com
INSERT, UPDATE,
eDELETE
operações.)Além disso, lembre-se da ordem dos campos no índice - quanto mais seletivo (cardinalidade maior) um campo, mais cedo no índice ele deve aparecer. Por exemplo, digamos que você esteja consultando automóveis usados:
Preço geralmente tem maior cardinalidade. Pode haver apenas algumas dezenas de cores disponíveis, mas possivelmente milhares de preços diferentes.
Dessas opções de índice,
idx01
fornece o caminho mais rápido para satisfazer a consulta:Isso ocorre porque menos carros satisfazem o preço do que a escolha da cor, dando ao mecanismo de consulta muito menos dados para analisar.
Eu sou conhecido por ter dois índices muito semelhantes, diferindo apenas na ordem dos campos para acelerar as consultas (nome, sobrenome) em um e (sobrenome, nome) no outro.
fonte
Um truque que aprendi recentemente é que o SQL Server pode atualizar variáveis locais e campos em uma instrução de atualização.
Ou a versão mais legível:
Usei isso para substituir cursores / junções complicados ao implementar cálculos recursivos e também obtive muito desempenho.
A seguir, detalhes e código de exemplo que fizeram melhorias fantásticas no desempenho: http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005---the-optimal. aspx
fonte
Assumindo o MySQL aqui, use EXPLAIN para descobrir o que está acontecendo com a consulta, verifique se os índices estão sendo usados da maneira mais eficiente possível e tente eliminar as classificações de arquivos. MySQL de alto desempenho: otimização, backups, replicação e muito mais é um ótimo livro sobre esse tópico, assim como o Blog de desempenho do MySQL .
fonte
@Terrapin, existem algumas outras diferenças entre isnull e coalescer que merecem ser mencionadas (além da conformidade com a ANSI, que é importante para mim).
Coalesce vs. IsNull
fonte
Às vezes, no SQL Server, se você usar um OR em uma cláusula where, ele realmente terá um desempenho. Em vez de usar o OR, basta fazer duas seleções e uni-las. Você obtém os mesmos resultados em 1000x a velocidade.
fonte
Veja a cláusula where - verifique o uso de índices / verifique se nada está sendo feito de bobo
fonte
Geralmente, começarei com as junções - eliminarei cada uma delas da consulta, uma de cada vez, e executarei novamente a consulta para ter uma idéia se houver uma junção específica com a qual estou tendo problemas.
fonte
Em todas as minhas tabelas temporárias, gosto de adicionar restrições exclusivas (quando apropriado) para criar índices e chaves primárias (quase sempre).
fonte
Eu criei o hábito de sempre usar variáveis de ligação. É possível que as variáveis de ligação não ajudem se o RDBMS não armazenar em cache instruções SQL. Mas se você não usar variáveis de ligação, o RDBMS não terá chance de reutilizar planos de execução de consultas e instruções SQL analisadas. A economia pode ser enorme: http://www.akadia.com/services/ora_bind_variables.html . Eu trabalho principalmente com Oracle, mas o Microsoft SQL Server funciona da mesma maneira.
Na minha experiência, se você não sabe se está ou não usando variáveis de ligação, provavelmente não está. Se o idioma do seu aplicativo não os suportar, encontre um que suporte. Às vezes, você pode corrigir a consulta A usando variáveis de ligação para a consulta B.
Depois disso, converso com nosso DBA para descobrir o que está causando mais dor no RDBMS. Observe que você não deve perguntar "Por que essa consulta é lenta?" É como pedir ao seu médico para tirar seu apêndice. Certifique-se de que sua consulta possa ser o problema, mas é provável que algo esteja errado. Como desenvolvedores, tendemos a pensar em termos de linhas de código. Se uma linha estiver lenta, corrija-a. Mas um RDBMS é um sistema realmente complicado e sua consulta lenta pode ser o sintoma de um problema muito maior.
Muitas dicas de ajuste de SQL são ídolos de cultos de carga. Na maioria das vezes, o problema não está relacionado ou está minimamente relacionado à sintaxe usada, portanto, normalmente é melhor usar a sintaxe mais limpa possível. Em seguida, você pode começar a procurar maneiras de ajustar o banco de dados (não a consulta). Apenas ajuste a sintaxe quando isso falhar.
Como qualquer ajuste de desempenho, sempre colete estatísticas significativas. Não use o tempo do relógio de parede, a menos que seja a experiência do usuário que você está ajustando. Em vez disso, observe coisas como tempo de CPU, linhas buscadas e blocos lidos no disco. Muitas vezes as pessoas otimizam para a coisa errada.
fonte
Primeira etapa: veja o plano de execução de consultas!
TableScan ->
aviso ruim de NestedLoop -> meh
TableScan atrás de um NestedLoop -> DOOM!
DEFINIR ESTATÍSTICAS IO ON
DEFINIR ESTATÍSTICAS HORA
fonte
Executar a consulta usando WITH (NoLock) é praticamente uma operação padrão em meu lugar. Qualquer um que for pego executando consultas nas tabelas de dezenas de gigabytes sem que seja retirado e filmado.
fonte
Converta as consultas NOT IN para JOYS OUTER ESQUERDA, se possível. Por exemplo, se você deseja encontrar todas as linhas na Tabela1 que não são usadas por uma chave estrangeira na Tabela2, você pode fazer isso:
Mas você obtém um desempenho muito melhor com isso:
fonte
@ DavidM
No SQL Server, o plano de execução oferece a mesma coisa: informa quais índices estão sendo atingidos, etc.
fonte
Indexe a (s) tabela (s) pelo (s) clm (s) filtrado (s)
fonte
Não necessariamente um truque de desempenho do SQL em si, mas definitivamente relacionado:
Uma boa idéia seria usar o memcached sempre que possível, pois seria muito mais rápido buscar os dados pré-compilados diretamente da memória do que obtê-los do banco de dados. Há também uma versão do MySQL que foi incorporada ao memcached (de terceiros).
fonte
Verifique se o comprimento do seu índice é o menor possível. Isso permite que o banco de dados leia mais chaves de cada vez no sistema de arquivos, acelerando suas junções. Suponho que isso funcione com todos os bancos de dados, mas sei que é uma recomendação específica para o MySQL.
fonte
Eu procuro:
fonte
Normalmente, a primeira linha dentro dos meus procedimentos armazenados, a menos que eu realmente precise usar
@@ROWCOUNT
.fonte
No SQL Server, use a diretiva nolock. Ele permite que o comando select seja concluído sem ter que esperar - geralmente outras transações serão concluídas.
fonte
Remova os cursores sempre que não forem necessários.
fonte
Remova as chamadas de função nos Sprocs, onde muitas linhas chamarão a função.
Meu colega usou chamadas de função (obtendo lastlogindate do userid como exemplo) para retornar conjuntos de registros muito amplos.
Com a otimização, substituí as chamadas de função no sproc pelo código da função: reduzi o tempo de execução de muitos sprocs de> 20 segundos para <1.
fonte
fonte
Eu gosto de usar
Sobre
Quando não preciso do suporte a múltiplos argumentos que a coalescência oferece.
http://blog.falafel.com/2006/04/05/SQLServerArcanaISNULLVsCOALESCE.aspx
fonte
Não prefixe os nomes dos Procedimentos armazenados com "sp_" porque todos os procedimentos do sistema começam com "sp_", e o SQL Server terá que procurar mais para encontrar seu procedimento quando for chamado.
fonte
Leituras sujas -
Impede bloqueios mortos onde a integridade transacional não é absolutamente necessária (o que geralmente é verdadeiro)
fonte
Eu sempre vou primeiro ao SQL Profiler (se é um procedimento armazenado com muitos níveis de aninhamento) ou ao planejador de execução de consulta (se são algumas instruções SQL sem aninhamento). 90% do tempo, você pode encontrar o problema imediatamente com uma dessas duas ferramentas.
fonte