Access
 sql >> Base de Dados >  >> RDS >> Access

Avaliando quando uma expressão em uma consulta é avaliada


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 o Trace 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.