Access
 sql >> Baza danych >  >> RDS >> Access

Obliczanie, kiedy wyrażenie w zapytaniu jest oceniane

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ś.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zestaw rekordów MS-Access i moduł klas

  2. Dostęp ODBC z Windows Server Core

  3. Tworzenie i dostęp do baz danych i tabel OLTP w pamięci

  4. TRANSACTION_MUTEX i dostęp do transakcji wielosesyjnych

  5. Czy Microsoft Access jest nadal aktualny w 2020 roku?