Zawsze uważałem, że doskonały wykres Itzika Ben-Gana dotyczący logicznego przetwarzania SQL jest niezwykle pomocny w wnioskowaniu o wydajności zapytań. Mimo że wykres został stworzony dla SQL Server, nadal ma zastosowanie do każdego silnika bazy danych zgodnego ze standardem SQL, który obejmuje również silnik bazy danych Access. Chociaż uwielbiamy korzystać z baz danych SQL Server, mamy sporadyczne bazy danych Access lub aplikacje Access, które wymagają użycia zapytań Access (np. tabel tymczasowych do raportowania). Access nie zawiera wymyślnych narzędzi do profilowania, więc co mamy zrobić?
Jerry montuje nasze własne narzędzie do śledzenia
To mnie zastanowiło — czy można określić, kiedy klauzula zapytania SQL zostanie wykonana i jak często? Program Access ma możliwość pokazania planów wykonania, ale nie wnika w szczegóły, jak i kiedy dane są przetwarzane. Istnieje okrężny sposób wnioskowania fizycznego kolejność przetwarzania używana przez silnik bazy danych Access:niestandardowa funkcja VBA!
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
Można to zapisać w standardowym module. Możemy wtedy ustawić prostą tabelę:
Śledzenie klauzul zapytania dostępu
Po takiej konfiguracji możemy utworzyć zapytanie programu Access i spryskać Trace
w różnych częściach zapytania programu Access. Oto jeden przykład:
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);
Jeśli następnie otworzysz zapytanie w widoku arkusza danych, a następnie przejdziesz do bezpośredniego okna VBIDE, powinieneś zobaczyć wyniki w następujący sposób:
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
Dzięki temu uzyskamy wgląd w to, w jaki sposób program Access rozwiązuje zapytanie, co może być przydatne, gdy trzeba zoptymalizować źle działające zapytanie. Zobaczmy, czego możemy się nauczyć:
- Widać, że jeśli nie ma odwołań do kolumn, funkcja VBA jest wywoływana tak wcześnie, jak to możliwe, ponieważ program Access rozpoznaje, że mogą one mieć tylko jedną wartość dla całego zestawu wyników, więc nie ma sensu wywoływanie funkcji raz za razem tylko aby uzyskać tę samą odpowiedź. Widać, że
Trace
wywołania bez drugiego opcjonalnego argumentu są oceniane jako pierwsze przed wszystkimi innymi wywołaniami zawierającymi odwołanie do kolumny w drugim opcjonalnym argumencie. - Nawiązując do poprzedniego punktu, jeśli wywołanie zawiera odwołanie do kolumny, musi być następnie ocenione co najmniej raz dla każdego wiersza. Możesz zobaczyć, że podczas oceny klauzuli przechodzimy przez każdą wartość koloru.
- Widzimy, że kolejność jest ogólnie podobna do tej, którą widzimy na wykresie Itzika Ben-Gana;
WHERE
jest oceniany tak wcześnie, jak to możliwe,ORDER BY
jest oceniane po wyeliminowaniu wszystkich niekwalifikujących się wierszy, a następnie co pozostało,SELECT
jest następnie oceniany. - Chociaż spodziewalibyśmy się, że sortowanie zostanie zastosowane po odfiltrowaniu niekwalifikujących się wierszy, wydaje się, że program Access woli próbować sortować dane wyjściowe tak szybko, jak to możliwe, prawdopodobnie dlatego, że tańsze jest wstawienie nowego wiersza do posortowanego lista nad sortowaniem całego zestawu.
Dodatkowe eksperymenty i wnioski
Możesz trochę poeksperymentować z innym zapytaniem. Na przykład możesz uzyskać wgląd w to, kiedy/często Access przetwarza GROUP BY
, używając zapytania podobnego do tego:
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;
Następnie możesz użyć tego w połączeniu z JetShowPlan, aby dowiedzieć się więcej o tym, co faktycznie robi silnik bazy danych. Mamy nadzieję, że okaże się to pomocne w zdobyciu wglądu w to, jak poprawić wydajność zapytania programu Access. Jako wyzwanie możesz wyjaśnić, dlaczego program Access wykonuje GROUP BY
sposób, w jaki to robi. Zachęcam również do eksperymentowania z otwieraniem arkusza danych i przewijaniem. Odkryjesz wtedy, że SELECT
zostanie ponownie oceniony w wyniku nawigacji.
Powinienem zaznaczyć, że powyższa technika zapewnia nam wgląd w fizyczne plan przetwarzania, a nie logiczną kolejność przetwarzania, jak opisano w tabeli. W związku z tym należy spodziewać się, że plan będzie inny dla różnych ilości danych lub dla różnych zapytań. Musimy również wziąć pod uwagę, że dodanie Trace
funkcja może mieć wpływ na plan. Twierdzę jednak, że jeśli jesteś tak zaniepokojony tymi względami, prawdopodobnie lepiej przenieść to zapytanie i jego dane bazowe do bazy danych SQL Server, gdzie masz znacznie więcej opcji optymalizacji wydajności zapytania.
Miłej zabawy!
Potrzebujesz pomocy z zapytaniami programu Microsoft Access? Zadzwoń do ekspertów Access pod numer (773) 809 5456 lub wyślij zespołowi wiadomość e-mail już dziś.