Sempre achei o excelente gráfico de Itzik Ben-Gan sobre o processamento lógico de SQL imensamente útil para raciocinar sobre o desempenho da consulta. Mesmo que o gráfico tenha sido feito para o SQL Server, ele ainda é aplicável a qualquer mecanismo de banco de dados que siga o SQL Standard, que também inclui o mecanismo de banco de dados Access. Embora gostemos de usar bancos de dados do SQL Server, temos bancos de dados ocasionais do Access ou aplicativos do Access que exigem o uso de consultas do Access (por exemplo, tabelas temporárias para relatórios). O Access não vem com ferramentas sofisticadas de criação de perfis, então o que devemos fazer?
Jerry-rigging nosso próprio utilitário de rastreamento
Isso me fez pensar - alguém poderia determinar quando uma cláusula de uma consulta SQL é executada e com que frequência? O Access tem um meio de mostrar os planos de execução, mas não entra nos detalhes de como e quando os detalhes são processados. Existe uma maneira indireta de inferir o valor físico ordem de processamento usada pelo mecanismo de banco de dados Access:uma função VBA personalizada!
Public Function Trace(EventName As String, Opcional Value As Variant) As Boolean If IsMissing(Value) Then Debug.Print EventName, "#No Value#" Else Debug.Print EventName, Value End If Trace =TrueEnd Function
Isso pode ser salvo em um módulo padrão. Podemos então montar uma tabela simples:
Rastreando as cláusulas de uma consulta de acesso
Com essa configuração, podemos criar uma consulta de acesso e polvilhar oTrace
em diferentes partes da consulta do Access. Aqui está um exemplo:
SELECT c1.ColorID, Trace("SELECT") AS Ignored1, Trace("SELECT",c1.Color) AS Ignored2FROM tblColor AS c1 WHERE Trace("WHERE") <> 0 AND Trace("WHERE", c1 .Color) <> 0ORDER BY Trace("ORDER BY"), Trace("ORDER BY", c1.Color);
Se você abrir a consulta no modo de folha de dados, vá para a janela imediata do VBIDE, você deverá ver a saída assim:
WHERE #No Value#ORDER BY #No Value#SELECT #No Value#WHERE RedORDER BY RedWHERE GreenORDER BY GreenWHERE BlueORDER BY BlueSELECT BlueSELECT GreenSELECT Red
Isso nos fornece alguns insights sobre como o Access está resolvendo a consulta, o que pode ser útil quando você precisa otimizar uma consulta com baixo desempenho. Vamos ver o que podemos aprender:
- Podemos ver que, se não houver referências de coluna, a função VBA é chamada o mais cedo possível, pois o Access reconhece que eles podem ter apenas um valor para todo o conjunto de resultados, portanto, não faz sentido chamar a função repetidamente apenas para obter a mesma resposta. Você pode ver que o
Trace
invocações sem o segundo argumento opcional foram avaliadas primeiro antes de todas as outras invocações contendo uma referência de coluna no segundo argumento opcional. - Como corolário do ponto anterior, se a invocação contém uma referência de coluna, ela deve ser avaliada pelo menos uma vez para cada linha. Você pode ver que passamos por cada valor de cor ao avaliar a cláusula.
- Vemos que a ordem é geralmente semelhante ao que vemos no gráfico de Itzik Ben-Gan;
WHERE
for avaliado o mais cedo possível,ORDER BY
é avaliado depois que eliminamos todas as linhas não qualificadas, então o que sobrar,SELECT
é então avaliado. - Embora esperemos que a classificação seja aplicada após filtrarmos as linhas não qualificadas, parece que o Access prefere tentar classificar a saída o mais rápido possível, possivelmente porque é mais barato inserir uma nova linha em uma list sobre a classificação de todo o conjunto.
Experiências e conclusões adicionais
Você pode experimentar um pouco com uma consulta diferente. Por exemplo, você pode obter uma visão sobre quando/frequentemente o Access processa
GROUP BY
, usando uma consulta semelhante a esta:SELECT c1.ColorID, Trace("SELECT") AS Ignored1FROM tblColor AS c1 INNER JOIN tblColor AS c2 ON c1.ColorID =c2.ColorIDWHERE Trace("WHERE") <> 0 AND Trace("WHERE", [c1 ].[Cor]) <> 0GROUP BY c1.ColorID, Trace("GROUP BY", c1.Color)ORDER BY c1.ColorID;
Você pode usar isso em conjunto com o JetShowPlan para saber mais sobre o que o mecanismo de banco de dados está realmente fazendo. Espero que você ache útil para obter insights sobre como melhorar o desempenho de sua consulta do Access. Como desafio, você pode raciocinar sobre por que o Access executa o
GROUP BY
do jeito que faz. Também encorajo você a experimentar abrir uma folha de dados e rolar. Você descobrirá então que o SELECT
é reavaliado como resultado da navegação. Devo salientar que a técnica acima nos fornece uma visão do físico plano de processamento, em vez da ordem lógica de processamento, conforme descrito no gráfico. Assim, devemos esperar que o plano seja diferente para diferentes volumes de dados ou para diferentes consultas. Também temos que considerar que adicionar o
Trace
função pode influenciar o plano. No entanto, eu diria que, se você está tão preocupado com essas considerações, provavelmente é melhor mover essa consulta e seus dados subjacentes para um banco de dados SQL Server, onde você tem muito mais opções para otimizar o desempenho da consulta. Divirta-se!
Precisa de ajuda com consultas do Microsoft Access? Ligue para os especialistas em acesso pelo telefone (773) 809 5456 ou envie um e-mail para a equipe hoje.