Siempre he encontrado que el excelente gráfico de Itzik Ben-Gan sobre el procesamiento lógico de SQL es inmensamente útil para razonar sobre el rendimiento de las consultas. Aunque el gráfico se creó para SQL Server, sigue siendo aplicable a cualquier motor de base de datos que siga el estándar SQL, que también incluye el motor de base de datos de Access. Aunque nos encanta usar bases de datos de SQL Server, tenemos bases de datos de Access ocasionales o aplicaciones de Access que requieren el uso de consultas de Access (por ejemplo, tablas temporales para informes). El acceso no viene con herramientas de perfilado de fantasía, entonces, ¿qué debemos hacer?
Diseñando nuestra propia utilidad de rastreo
Eso me hizo preguntarme:¿se podría determinar cuándo se ejecuta una cláusula de una consulta SQL y con qué frecuencia? Access tiene un medio para mostrar los planes de ejecución, pero no entra en los detalles de cómo y cuándo se procesan los detalles. Hay una forma indirecta de inferir lo físico orden de procesamiento utilizado por el motor de la base de datos de Access:¡una función VBA personalizada!
Public Function Trace(EventName As String, Optional Value As Variant) As Boolean If IsMissing(Value) Then Debug.Print EventName, "#No Value#" Else Debug.Print EventName, Value End If Trace = True End Function
Esto se puede guardar en un módulo estándar. Luego podemos configurar una tabla simple:
Rastreo de las cláusulas de una consulta de Access
Con esa configuración, podemos crear una consulta de Access y esparcir el Trace
en diferentes partes de la consulta de Access. He aquí un ejemplo:
SELECT c1.ColorID, Trace("SELECT") AS Ignored1, Trace("SELECT",c1.Color) AS Ignored2 FROM tblColor AS c1 WHERE Trace("WHERE") <> 0 AND Trace("WHERE", c1.Color) <> 0 ORDER BY Trace("ORDER BY"), Trace("ORDER BY", c1.Color);
Si luego abre la consulta en la vista de hoja de datos, luego pasa a la ventana inmediata de VBIDE, debería ver el resultado como este:
WHERE #No Value# ORDER BY #No Value# SELECT #No Value# WHERE Red ORDER BY Red WHERE Green ORDER BY Green WHERE Blue ORDER BY Blue SELECT Blue SELECT Green SELECT Red
Esto nos brinda información sobre cómo Access resuelve la consulta, lo que puede ser útil cuando necesita optimizar una consulta con un rendimiento deficiente. Veamos qué podemos aprender:
- Podemos ver que si no hay referencias de columna, la función de VBA se llama lo antes posible, ya que Access reconoce que solo pueden tener un valor para todo el conjunto de resultados, por lo que no tiene sentido llamar a la función una y otra vez solo para obtener la misma respuesta. Puedes ver que el
Trace
las invocaciones sin el segundo argumento opcional se evaluaron primero antes que todas las demás invocaciones que contenían una referencia de columna en el segundo argumento opcional. - Como corolario del punto anterior, si la invocación contiene una referencia de columna, debe evaluarse al menos una vez para cada fila. Puede ver que revisamos cada valor de color al evaluar la cláusula.
- Vemos que el orden es generalmente similar al que vemos en el gráfico de Itzik Ben-Gan;
WHERE
se evalúa lo antes posible,ORDER BY
se evalúa después de que hayamos eliminado todas las filas que no califican, luego lo que quede,SELECT
luego se evalúa. - Aunque esperaríamos que se aplicara la ordenación después de filtrar las filas que no califican, parece que Access prefiere intentar ordenar la salida lo antes posible, posiblemente porque es más económico insertar una nueva fila en una fila ordenada. lista sobre la clasificación de todo el conjunto.
Experimentos adicionales y conclusiones
Puedes experimentar un poco con una consulta diferente. Por ejemplo, puede obtener información sobre cuándo/a menudo Access procesa GROUP BY
, utilizando una consulta similar a esta:
SELECT c1.ColorID, Trace("SELECT") AS Ignored1 FROM tblColor AS c1 INNER JOIN tblColor AS c2 ON c1.ColorID = c2.ColorID WHERE Trace("WHERE") <> 0 AND Trace("WHERE", [c1].[Color]) <> 0 GROUP BY c1.ColorID, Trace("GROUP BY", c1.Color) ORDER BY c1.ColorID;
Luego puede usar esto junto con JetShowPlan para obtener más información sobre lo que realmente está haciendo el motor de la base de datos. Con suerte, puede resultarle útil para obtener información sobre cómo puede mejorar el rendimiento de su consulta de Access. Como desafío, podría razonar por qué Access ejecuta GROUP BY
la forma en que lo hace. También lo animo a que experimente abriendo una hoja de datos y desplazándose. Entonces descubrirá que SELECT
se vuelve a evaluar como resultado de la navegación.
Debo señalar que la técnica anterior nos proporciona una idea de lo físico plan de procesamiento, en lugar del orden de procesamiento lógico como se describe en el gráfico. En consecuencia, debemos esperar que el plan sea diferente para diferentes volúmenes de datos o para diferentes consultas. También tenemos que considerar que agregar el Trace
función puede influir en el plan. Sin embargo, diría que si está tan preocupado por esas consideraciones, probablemente sea mejor mover esa consulta y sus datos subyacentes a una base de datos de SQL Server donde tiene muchas más opciones para optimizar el rendimiento de la consulta.
¡Diviértete!
¿Necesita ayuda con las consultas de Microsoft Access? Llame a Access Experts al (773) 809 5456 o envíe un correo electrónico al equipo hoy.