O ajuste de consulta deve ser proativo ou reativo?

23

Como desenvolvedor de software e um DBA aspirante, tento incorporar as práticas recomendadas ao criar meus bancos de dados do SQL Server (99% do tempo em que meu software fica sobre o SQL Server). Eu faço o melhor design possível antes e durante o desenvolvimento.

Mas, como qualquer outro desenvolvedor de software, há funcionalidades adicionais, bugs e apenas mudanças de requisitos que exigem objetos de banco de dados alterados / criados.

Minha pergunta é: o ajuste de consulta deve ser proativo ou reativo? Em outras palavras, algumas semanas após algumas modificações pesadas no código / banco de dados, devo reservar um dia para verificar o desempenho da consulta e ajustar com base nisso? Mesmo que pareça estar funcionando bem ?

Ou devo apenas estar ciente de que o desempenho abaixo da média deve ser uma verificação do banco de dados e voltar ao quadro negro?

O ajuste da consulta pode levar muito tempo e, dependendo do design inicial do banco de dados, pode ser um benefício mínimo. Estou curioso quanto ao modus operandi aceito.

Thomas Stringer
fonte
7
Otimização prematura é a raiz de todos os males - DonaldKnuth
Drasill
@ Drill, você pode expandir isso? Mal como no tempo perdido de desenvolvimento?
Thomas Stringer
na verdade, sua pergunta me fez pensar nessa citação famosa ( consulte o google ). Mas é mais voltado para o desenvolvimento de software, acho que realmente não se encaixa no DBA. Por fim, eu diria que "a micro otimização prematura é má".
Drasill 5/09/11
Ver também um velho codificação pós horror sobre este assunto :)
Drasill

Respostas:

17

Ambos, mas principalmente proativos

É importante testar durante o desenvolvimento os volumes e a qualidade dos dados realistas. É inacreditavelmente comum ter uma consulta em execução em desenvolvedores de 100 ou 1000 linhas e depois cair horizontalmente com 10 milhões de linhas de produção.

Ele permite que você faça anotações também sobre "o índice pode ajudar aqui". Ou "revisite-me". Ou "será corrigido com o novo recurso xxx na próxima versão do banco de dados".

No entanto, algumas consultas não resistem ao teste do tempo. A distribuição de dados é alterada ou fica exponencial porque o otimizador decide usar um tipo de junção diferente. Nesse caso, você só pode reagir.

Dizendo que, pelo menos para o SQL Server, as várias consultas DMV de "índice ausente" e "consulta mais longa" podem indicar áreas problemáticas antes da chamada telefônica

Editar: para esclarecer ...

Proativo não significa ajustar todas as consultas agora. Significa ajustar o que você precisa (frequentemente executado) para um tempo de resposta razoável. Ignore principalmente as consultas semanais às 3 da manhã de domingo.

gbn
fonte
16

OK, vou morder e ter uma visão contrária. Primeiro, eu diria que você nunca deve começar fazendo algo que sabe que o levará a problemas. Se você deseja chamar isso de melhores práticas de aplicação, vá em frente. Isso é o máximo que deve ser proativo.

Depois disso, o tempo (e dinheiro) é desperdiçado, então continue com ele e entregue seu produto. Em vez de dedicar muito tempo ao design, ajustando consultas que podem ou não se tornar gargalo, use esse tempo para testes extras, incluindo testes de carga.

Quando você descobrir que algo não está executando de acordo com as especificações do seu projeto, ou se algo estiver entre os 10% ou 20% mais baixos da lista de tempos de resposta do seu perfil, invista o tempo necessário para ajustar o que quer que seja quebrado.

Em um mundo perfeito, tudo seria projetado perfeitamente desde o início e desenvolvido usando uma sequência de construção lógica. No mundo real, existem restrições de orçamento e tempo e seus dados de teste podem não acabar se parecendo com os dados de produção. Por esse motivo, digo que use o bom senso para evitar problemas de maneira proativa, mas concentre seus recursos limitados ajustando as coisas que acabam sendo problemas reais, em vez de gastar tempo e dinheiro que você provavelmente não tem em procurar problemas imaginários ou potenciais.

Joel Brown
fonte
3
Eu não acho que isso seja contrário. Ninguém está sugerindo que você deva otimizar tudo preventivamente, mas você deve testar tudo e otimizar as coisas que são evidentes para que elas possam / causem problemas na produção. Isso é bem diferente da otimização do código sem dados e da descoberta do que está quebrado / lento após a entrega do código. Claro que há uma linha - como você mencionou, você precisa entregar algo eventualmente. Mas acho que há um bom equilíbrio lá onde você pode evitar entregar algo que é péssimo em termos de desempenho.
Aaron Bertrand
4
Aaron, concordou - nunca forneça nada que chame a atenção em termos de desempenho e não carregue e construa algo sem pensar muito sobre desempenho e escalabilidade. "Meça duas vezes, corte uma vez" pertence aos adesivos dos programadores tanto quanto aos carpinteiros. Ao mesmo tempo, senti que o teor geral das outras respostas era "proativo> reativo" e senti que havia uma opinião sub-representada de que "realidade == reativa" e, portanto, a chave é não perder tanto tempo sendo proativo que você não tem tempo ou dinheiro sobrando para lidar com as duras realidades, geralmente imprevisíveis.
Joel Brown
15

Você fará 3 tipos de ajuste, 1 reativo e 2 proativo.

Reativo

Do nada, algumas consultas começam a causar problemas. Pode ser por causa de um bug ou recurso do aplicativo, uma tabela crescendo acima das expectativas, um pico de tráfego ou o otimizador de consultas ficando "criativo". Esse pode ser um caso do tipo no meio da noite, oh porcaria do site, ou pode ser uma resposta à lentidão do sistema de natureza não crítica. De qualquer maneira, o caráter definidor da sintonia reativa é que você já tem um problema . Escusado será dizer que você quer fazer o mínimo possível disso. O que nos leva a ...

Proativo

Tipo 1: Manutenção de rotina

Em algum tipo de agendamento, a cada poucos meses ou semanas, dependendo da frequência com que o esquema muda e da rapidez com que seus dados crescem, você deve revisar a saída das ferramentas de análise de desempenho do banco de dados (por exemplo, relatórios AWR para DBAs do Oracle). Você está procurando por problemas incipientes, que são coisas que estão a caminho de exigir ajuste Reativo, além de frutas baixas, itens que provavelmente não causarão problemas em breve, mas que podem melhorar com pouco esforço na esperança de evitar longe. problemas futuros. Quanto tempo você deve gastar com isso dependerá de quanto tempo você tem e do que mais você poderia estar gastando, mas a quantidade ideal nunca é zero. No entanto, você pode facilmente reduzir o valor necessário gastando mais de ...

Tipo 2: Design Adequado

A advertência de Knuth contra a "otimização prematura" é amplamente conhecida e devidamente respeitada. Mas a definição adequada de "prematuro" deve ser usada. Alguns desenvolvedores de aplicativos, quando autorizados a escrever suas próprias consultas, tendem a adotar a primeira consulta que eles encontrarem que é logicamente correta e não se importam com o desempenho, presente ou futuro. Ou eles podem testar um conjunto de dados de desenvolvimento que simplesmente não é representativo do ambiente de produção (dica: não faça isso! Os desenvolvedores sempre devem ter acesso a dados realistas para teste.). O ponto é que o momento adequado para ajustar uma consulta é quando ela é implantada pela primeira vez, não quando aparece em uma lista de SQL com baixo desempenho e, definitivamente, não quando causa um problema crítico.

Então, o que qualificaria como uma otimização prematura no território do DBA? No topo da minha lista estaria sacrificando a normalização sem uma necessidade demonstrada. Claro que você pode manter uma soma em uma linha pai em vez de calculá-la em tempo de execução a partir das linhas filho, mas você realmente precisa? Se você é Twitter ou Amazon, a desnormalização estratégica e o pré-cálculo podem ser seus melhores amigos. Se você estiver projetando um pequeno banco de dados contábil para 5 usuários, a estrutura adequada para facilitar a integridade dos dados precisará ser a principal prioridade. Outras otimizações prematuras também são uma questão de prioridades. Não gaste horas ajustando uma consulta que é executada uma vez por dia e leva 10 segundos, mesmo se você acha que pode reduzi-la para 0,1 segundos. Talvez você tenha um relatório que é executado por 6 horas diariamente, mas explore a programação como um trabalho em lotes antes de investir tempo em ajustá-lo. Não invista em uma instância separada de relatórios replicados em tempo real se sua carga de produção nunca flutuar acima de 10% (supondo que você possa gerenciar a segurança).

Ao testar dados realistas, adivinhar suposições educadas sobre padrões de crescimento e tráfego (além de provisões para picos) e aplicar seu conhecimento das peculiaridades do otimizador da plataforma, você pode implantar consultas que executam (perto de) de forma otimizada não apenas agora, mas no futuro , e sob condições abaixo do ideal. Quando você aplica as técnicas apropriadas, o desempenho da consulta pode ser previsto com precisão e otimizado (no sentido de cada componente ser o mais rápido possível).

(E enquanto você está nisso, aprenda estatísticas! )

Noah Yetter
fonte
O design adequado representa 95% do desempenho e escalabilidade.
Mark Stewart
6

Em um mundo perfeito, todos os ajustes seriam feitos na fase de design de maneira proativa e nada seria reativo, mas o mundo não é perfeito. Você descobrirá que os dados de teste às vezes não são representativos, os casos de teste serão perdidos, as cargas serão inesperadamente diferentes e haverá erros que causam problemas de desempenho. Essas situações podem exigir algum ajuste reativo, mas isso não significa que o ajuste reativo seja preferido. O objetivo sempre deve ser alcançá-los com antecedência.

Seu planejamento para o ajuste retroativo é muito pragmático. Ao fazer o teste, você deve documentar os tempos e a taxa de transferência esperados e, às vezes, deve criar uma análise que permita saber quando os processos de produção não estão atendendo às especificações do projeto. Dessa maneira, você poderá identificar antecipadamente qual código precisa ser ajustado. Você pode determinar não apenas qual é o problema, mas por que não o pegou na fase de design / teste.

Leigh Riffel
fonte
5

Para mim, o teste de desempenho sempre fez parte do processo de desenvolvimento. Deseja alterar esta tabela, alterar este relatório, adicionar este recurso? Como parte do teste, você pode comparar o desempenho individual e geral com as linhas de base conhecidas e / ou com os requisitos (por exemplo, alguns relatórios são executados em segundo plano ou são automatizados de outra forma, portanto, o desempenho - ou melhor, a velocidade - de cada consulta no sistema nem sempre é a principal prioridade).

IMHO, isso não deve ser um processo reativo - você nunca deve esperar até que uma mudança cause um problema de desempenho na produção para começar a reagir a ela. Ao fazer a alteração no desenvolvimento / teste, etc., você deve testar essas alterações com dados semelhantes em hardware semelhante, com os mesmos aplicativos e padrões de uso semelhantes. Não deixe que essas mudanças sejam levadas rapidamente para a produção e surpreendê-lo. Isso quase sempre acontece quando não é conveniente passar um dia afinando - o orçamento para esse tempo de afinação com bastante antecedência.

Aaron Bertrand
fonte