Dicas de otimização de consulta do SQL Server 2005/8

13

Estou procurando educar uma equipe para escrever consultas melhores do SQL Server e queria saber quais seriam as melhores dicas das pessoas para melhorar o desempenho.

Por exemplo, uma vez eu tive um DBA que insistiu que a contagem (*) teria um desempenho pior que a contagem (1) (não tenho idéia se ela estava certa ou se ainda é válida nos últimos otimizadores de consulta).

Que coisas simples devo dizer à equipe para tentar sempre usar ou evitar? Idealmente, estou procurando coisas que (a) possam fazer uma diferença razoável e (b) sejam diretas, 1 a 2 linhas para afirmar.

Jon Hopkins
fonte

Respostas:

13

Ajuste de consulta 101

Não existe uma bala de prata mágica para consultar o ajuste, embora eu possa lhe dar algumas dicas e sugestões. A primeira coisa a fazer é entender o que realmente está acontecendo nos bastidores. Obtenha um bom livro interno, como o terceiro livro do Guia do Guru.

As consultas com desempenho insatisfatório tendem a aparecer em dois tipos básicos: consultas transacionais que demoram muito e moagem de tarefas em lote (ou relatórios) que demoram muito. Um bom sinal de uma consulta com algo errado é um único item no plano de consulta que leva 99% do tempo.

Consultas transacionais

Na maioria das vezes, uma consulta transacional com baixo desempenho é uma das poucas coisas:

  • Um índice ausente. Você pode ver isso no plano de consulta - varreduras de tabelas de tabelas grandes em uma junção que devem ser muito seletivas (por exemplo, retornar algumas linhas).

  • Consulta incapaz de usar um índice. Se você tiver condições OR na cláusula where, ingressar em um valor calculado ou em algum outro item da consulta que não seja capaz de sarg, talvez seja necessário reescrever a consulta. Resumidamente, os sargs são predicados de consulta que podem usar índices para eliminar linhas. AND lógico, igualdade e desigualdade (>,> =, <, <= e! =) São todos sargable. Tradicionalmente, o OR não é sargable. No entanto, é possível converter ORs em predicados sargable invertendo o sentido das construções do tipo OR para NOT (foo e não bar).

  • Predicados ineficientes. Por exemplo, se você tiver uma where inreferência a uma subconsulta aninhada, veja se ela pode ser reescrita como where existsou como uma associação. Isso pode resultar em planos de consulta mais eficientes e aqui estão outras reescrições padrão que você pode tentar também. Novamente, os livros de guia do Guru e outros sobre o assunto são um bom ponto de partida.

Consultas em lote

As consultas em lote são mais complicadas e têm problemas de ajuste diferentes. Algumas dicas são:

  • Indexação. Isso pode fazer uma grande diferença pelo mesmo motivo que ocorre com consultas transacionais. Freqüentemente, um bom sinal de um índice ausente é uma operação longa e complicada (99% do plano de consulta) que parece não estar atrapalhando a máquina.

  • Tabelas temporárias. Você pode achar melhor dividir uma consulta em várias consultas que preenchem tabelas temporárias. Consultas maiores dão ao otimizador mais espaço para estragar tudo, embora esse seja um problema menor do que costumava ser. Crie as tabelas temporárias com select intoessa operação registrada minimamente (muito menos atividade de log), o que reduz a carga de E / S.

    Observe que as tabelas temporárias no tempdb são a mesma estrutura de dados que o otimizador usa para armazenar resultados intermediários de junção, portanto, não há penalidade de desempenho por fazer isso. Você também pode criar um índice (incluindo índices agrupados e de cobertura) em uma tabela temporária, o que pode melhorar o desempenho das consultas que estão sendo lidas pelos mesmos motivos pelos quais elas melhoram as consultas em tabelas estáticas.

    Não exagere nas tabelas temporárias, pois elas podem dificultar o rastreamento das consultas. Para tabelas menores em um procedimento armazenado, teste para ver se as variáveis ​​da tabela ajudam. Essa é uma estrutura de dados na memória, para que possa ser uma conquista de desempenho.

  • Índices agrupados e de cobertura. Isso pode melhorar o desempenho de uma consulta, pois força a localidade de referência no disco com base em alguma coluna de agrupamento. Um índice em cluster pode fazer uma grande diferença no desempenho de um trabalho em lotes.

  • Predicados ineficientes. Isso pode causar problemas com sargs e outras sub-otimizações, da mesma maneira que ocorre com consultas transacionais.

  • O escaneamento de mesa é seu amigo. Ao contrário da crença popular, as varreduras de mesa não são inerentemente más. Geralmente eles são um sinal de algo errado em uma consulta transacional, mas geralmente são a maneira mais eficiente de executar uma operação em lote grande. Se você estiver fazendo algo com mais de alguns por cento de linhas em uma tabela, uma varredura de tabela geralmente é a maneira mais eficiente de cobrir a tabela.

  • Loops aninhados se juntam. Veja o que o otimizador está fazendo nos dois lados da união. Eles podem ser ineficientes se você estiver (por exemplo, tabela varrendo duas tabelas grandes em ambos os lados de uma junção de loops aninhados. Considere o uso de índices em cluster ou order bytente alterar a operação para uma junção de mesclagem ou dicas para promover uma junção de hash se um lado estiver pequeno o suficiente para fazer isso.

Travamento

O bloqueio também pode causar problemas de desempenho. Se seu sistema estiver com um desempenho ruim sob carga, consulte os contadores de criação de perfil e perfmon relacionados a bloqueios e verifique se há alguma contenção significativa. sp_who2possui uma coluna 'BlkBy' no conjunto de resultados que mostra se uma consulta está bloqueada e o que está bloqueando. Além disso, perfis com eventos 'gráfico de deadlock' (se você tiver consultas com deadlock) e eventos relacionados ao bloqueio podem ser úteis para solucionar problemas de bloqueio.

ConcernedOfTunbridgeWells
fonte
1
+1, pois essas são algumas ótimas informações sobre ajuste de desempenho (tive o prazer de participar das aulas de Kalen. Ela sabe do que se trata!). Você pode adicionar algumas informações sobre visualizações dinâmicas.
711 Wayne
3

Melhor dica: use o SQL Server 2008 e execute o Activity Monitor enquanto seus testes estão em execução. Observe as consultas que demoram mais / têm mais E / S, etc. Clique com o botão direito do mouse nessas consultas para visualizar a consulta e / ou o plano de execução.

Próximo: aprenda a entender os planos de execução.

Próximo: Use o assistente de ajuste do banco de dados.

Essas etapas ajudarão você a gerar suas próprias "melhores dicas".

John Saunders
fonte
2

Um excelente e-book gratuito da RedGate disponível sobre como trabalhar e entender os planos de execução do SQL Server

http://www.red-gate.com/specials/Grant.htm?utm_content=Grant080623

Shameless Plug, refiro materiais de ajuste de desempenho no meu blog no SQL Server Performance .

Depois de ter a oportunidade de digerir parte desse material, sinta-se à vontade para postar aqui ou entrar em contato comigo diretamente com perguntas específicas.

John Sansom
fonte
1

Primeiro, indexação. Muitas pessoas não percebem que chaves estrangeiras não obtêm índices automaticamente. Como eles são usados ​​em junções, eles quase sempre devem ter um índice.

Examine atentamente todos os cursores para ver se eles podem ser substituídos pelo código baseado em conjunto. Alterei o código que foi executado por horas a segundos ao fazer isso.

Evite subconsultas. Se você os tiver no código, substitua-os por junções ou junções a tabelas derivadas.

Verifique se sua cláusula where é sargável.

Aprenda a ler planos de execução.

Verifique se o escritório possui alguns bons livros sobre ajuste de desempenho.

As variáveis ​​de tabela são melhores que as tabelas temporárias em algumas instâncias e as tabelas temporárias têm melhor desempenho em outras. Se você precisar usá-las, tente as duas e veja qual funciona melhor nesse caso específico.

HLGEM
fonte