Ho sempre trovato l'eccellente grafico di Itzik Ben-Gan sull'elaborazione logica SQL immensamente utile per ragionare sulle prestazioni di query. Anche se il grafico è stato creato per SQL Server, è ancora applicabile a qualsiasi motore di database che segue SQL Standard, che include anche il motore di database di Access. Sebbene amiamo usare i database di SQL Server, abbiamo occasionali database di Access o applicazioni di Access che richiedono l'uso di query di Access (ad es. tabelle temporanee per la creazione di report). L'accesso non viene fornito con strumenti di profilazione fantasiosi, quindi cosa dobbiamo fare?
Jerry-rigging la nostra utilità di traccia
Questo mi ha portato a chiedermi:si potrebbe determinare quando una clausola di una query SQL viene eseguita e con quale frequenza? Access ha un mezzo per mostrare i piani di esecuzione ma non entra nei dettagli di come e quando i dettagli vengono elaborati. C'è un modo indiretto per dedurre il fisico ordine di elaborazione utilizzato dal motore di database di Access:una funzione VBA personalizzata!
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
Questo può essere salvato in un modulo standard. Possiamo quindi impostare una semplice tabella:
Tracciamento delle clausole di una query di Access
Con questa configurazione, possiamo creare una query di Access e spruzzare il Trace
in diverse parti della query di Access. Ecco un esempio:
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);
Se quindi apri la query nella visualizzazione foglio dati, quindi vai alla finestra immediata di VBIDE, dovresti vedere l'output in questo modo:
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
Questo ci fornisce alcune informazioni su come Access risolve la query che può essere utile quando è necessario ottimizzare una query con prestazioni scadenti. Vediamo cosa possiamo imparare:
- Possiamo vedere che se non ci sono riferimenti di colonna, la funzione VBA viene chiamata il prima possibile poiché Access riconosce che possono avere un solo valore per l'intero set di risultati, quindi non ha senso chiamare la funzione ancora e ancora solo per ottenere la stessa risposta. Puoi vedere che il
Trace
le chiamate senza il 2° argomento facoltativo sono state valutate prima di tutte le altre chiamate contenenti un riferimento a una colonna nel 2° argomento facoltativo. - Come corollario del punto precedente, se l'invocazione contiene un riferimento di colonna, deve essere valutato almeno una volta per ogni riga. Puoi vedere che esaminiamo ogni valore di colore quando valutiamo la clausola.
- Vediamo che l'ordine è generalmente simile a quello che vediamo nel grafico di Itzik Ben-Gan;
WHERE
viene valutato il prima possibile,ORDER BY
viene valutato dopo aver eliminato tutte le righe non qualificanti, quindi tutto ciò che rimane,SELECT
viene quindi valutato. - Sebbene ci si aspetterebbe che l'ordinamento venga applicato dopo aver filtrato le righe non qualificanti, sembra che Access preferisca provare a ordinare l'output il prima possibile, probabilmente perché è più economico inserire una nuova riga in un ordine elenco sull'ordinamento dell'intero set.
Ulteriori esperimenti e conclusioni
Puoi sperimentare un po' con una query diversa. Ad esempio, puoi ottenere informazioni dettagliate su quando/spesso Accede ai processi GROUP BY
, utilizzando una query simile a questa:
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;
È quindi possibile utilizzarlo insieme a JetShowPlan per ulteriori informazioni sulle operazioni effettivamente eseguite dal motore di database. Si spera che possa essere utile per ottenere informazioni dettagliate su come migliorare le prestazioni della query di Access. Come sfida, potresti spiegare perché Access esegue il GROUP BY
il modo in cui lo fa. Ti incoraggio anche a sperimentare l'apertura di un foglio dati e lo scorrimento. Scoprirai quindi che il SELECT
viene rivalutato a seguito della navigazione.
Vorrei sottolineare che la tecnica sopra ci fornisce informazioni sul fisico piano di elaborazione, piuttosto che l'ordine di elaborazione logico come descritto nel grafico. Di conseguenza, dovremmo aspettarci che il piano sia diverso per diversi volumi di dati o per query diverse. Dobbiamo anche considerare che aggiungendo il Trace
funzione può influenzare il piano. Tuttavia, direi che se sei così preoccupato per queste considerazioni, probabilmente è meglio spostare quella query e i suoi dati sottostanti in un database di SQL Server in cui hai molte più opzioni per ottimizzare le prestazioni della query.
Buon divertimento!
Hai bisogno di aiuto con le query di Microsoft Access? Chiama gli esperti di accesso al numero (773) 809 5456 o invia un'email al team oggi stesso.