Banco de Dados

30 mar, 2016

Sobre SQL Hints, humildade e canja de galinha

Publicidade

Dicas SQL (ou “SQL hints” em inglês) são instruções avançadas que permitem forçar o SGBD a agir de forma predeterminada.

A ideia é oferecer aos DBAs e desenvolvedores recursos para conseguir uma sintonia fina de consultas e operações do SGBD, com objetivos específicos, tais como melhorar performance, reduzir ocorrência de bloqueios (os famosos “locks”), reaproveitar e/ou recriar planos de execução etc.

De fato, as dicas SQL aumentam a versatilidade da linguagem SQL em casos em que otimizador de consultas não atinge os resultados desejados.

Mas, como se costuma dizer por aí, não existe almoço grátis. Tudo tem prós e contras, e esse é o tema que eu abordo a seguir.

Noções básicas sobre dicas SQL

Cada SGBD tem um conjunto ligeiramente diferente de dicas suportadas. No caso do SQL Server, elas podem ser agrupadas da seguinte maneira:

  • Dicas sobre Junções
  • Dicas sobre Consultas
  • Dicas sobre Tabelas

Dicas sobre Junções: quando se usa uma junção na cláusula FROM de uma declaração SQL (INNER JOIN, LEFT JOIN etc.), o otimizador de consultas avalia as estatísticas e define de que forma essa operação será executada internamente. Dependendo de suas características, as junções são executadas internamente, usando os métodos HASH, LOOP ou MERGE JOIN.

Quando essa declaração usa uma dica de junção, nós forçamos o otimizador a usar um método específico. Por exemplo:

SELECT * FROM T1 INNER HASH JOIN T2 ON T1.Campo1 = T2.Campo1

No caso acima, o otimizador é forçado a usar o método HASH para junção das tabelas T1 e T2. (Ao leitor que quiser conhecer detalhes de uso de cada dica SQL, recomendo consultar as Leituras Sugeridas).

Dicas sobre Consultas: estabelecem uma série de opções de execução de consultas, como métodos de execução de GROUP BY e ORDER BY, comportamento da consulta em relação ao bloqueio de objetos envolvidos, forma de exibição de resultados etc.

Provavelmente a dica SQL mais conhecida deste grupo é o WITH NOLOCK, que permite a execução de consultas sem que a tabela referenciada seja bloqueada. Isso garante maior disponibilidade dos objetos consultados dentro de um ambiente em que exista alta concorrência. Nenhuma transação terá que aguardar a execução dessa consulta, já que as tabelas envolvidas não serão bloqueadas. Em consequência disso, garante um desempenho melhor da aplicação como um todo.

Em contrapartida, ao usarmos a dica NOLOCK, estamos sacrificando a qualidade dos resultados da consulta, já que outras transações podem alterar os valores que ela leu enquanto a consulta ainda estiver sendo executada. Isso é um problema, porque as outras transações podem fazer COMMIT ou ROLLBACK durante a execução da consulta sem que isso se reflita nos resultados apresentados. Portanto, estamos abrindo mão da exatidão dos resultados quando executamos uma consulta com a opção WITH NOLOCK.

Dicas sobre Tabelas: estabelecem comportamentos de operação de tabelas e seus índices. Incluem operações de bloqueio (ou “LOCKS”), métodos de leitura (READCOMMITED etc.), métodos de uso de índices (FORCESEEK etc.).
Uma das dicas mais interessantes deste grupo é, em minha opinião, a dos índices filtrados. Essa opção permite criar um índice para valores específicos de um campo. Por exemplo:

CREATE NONCLUSTERED INDEX ixExemplo
ON T1 (Campo2)
WHERE Campo2 IN (10, 100, 1000);

Não existe almoço grátis

Dicas SQL devem ser usadas em situações muito específicas e muito bem estudadas. Mas a simplicidade da sintaxe incentiva profissionais despreparados a usá-las sem o devido cuidado.

Na prática, quando o profissional usa dicas SQL, ele está dizendo para o otimizador de consultas “deixa comigo que eu sei o que eu estou fazendo”. Óbvio que isso raramente é verdade.

Como eu costumo dizer, não há nada pior do que profissionais sem modéstia e sem noção. Humildade, assim como a canja de galinha, nunca fez mal a ninguém.

O otimizador de consultas do SGBD é uma ferramenta sofisticada, que usa algoritmos matemáticos que analisam dezenas de variáveis e baseiam suas decisões nas estatísticas de uso do banco.

Em teoria, as decisões do otimizador são adequadas para o instante em que a operação está sendo executada.

Como as dicas SQL desprezam a recomendação do otimizador e forçam a execução da consulta de uma maneira pré-determinada, pode-se dizer que neste caso usamos uma solução engessada.

A impressão que eu tenho é que muitos analistas usam dicas SQL como “modismo”: viram algum colega conseguindo bons resultados usando dicas SQL e acham que elas vão resolver os seus problemas também.

Não é assim que a coisa funciona no mundo real. É preciso ter uma justificativa muito boa para se desprezar as recomendações do otimizador (considerando que as estatísticas estejam devidamente atualizadas).

Para se ter uma ideia da seriedade dessa questão, a documentação oficial da Microsoft recomenda muito cuidado no uso de dicas SQL, que, segundo ela, devem ser utilizadas somente como último recurso e por DBAs e desenvolvedores experientes.

Portanto, ninguém pode alegar desconhecimento do assunto. Dicas SQL são destinadas a situações muito especiais.

Em 2014, eu e o colega Paulo Roberto Elias publicamos um artigo em que apresentávamos um caso de sucesso de uso de dicas SQL. Tratava-se do uso da dica HASH JOIN, que melhorava muito a performance de uma consulta, mas isso acontecia em razão de certas particularidades dos objetos envolvidos (vide Leituras Sugeridas).

Conclusão

Dicas SQL são recursos muito poderosos e podem ajudar a solucionar problemas complexos no seu banco de dados.

Mas, como todo remédio, causarão problemas ainda maiores se usadas do modo errado. Dicas são úteis somente em situações muito bem definidas e bem estudadas, visto que vão criar uma solução engessada na maioria dos casos.

Portanto, a recomendação é clara. Deixe as dicas SQL para serem usadas quando nenhuma alternativa estudada tenha surtido o efeito esperado. Seu SGBD agradece.

Leituras Sugeridas

***

Artigo publicado originalmente na Revista iMasters.