Винаги съм намирал отличната диаграма на Ицик Бен-Ган за логическата обработка на SQL изключително полезна при разсъжденията относно ефективността на заявките. Въпреки че диаграмата е направена за SQL Server, тя все още е приложима за всеки двигател на база данни, който следва SQL Standard, който също включва машина за база данни на Access. Въпреки че обичаме да използваме бази данни на SQL Server, ние от време на време имаме бази данни на Access или приложения на Access, които изискват използването на заявки на Access (например временни таблици за отчитане). Достъпът не идва с елегантни инструменти за профилиране, така че какво да правим?
Джери монтира нашата собствена програма за проследяване
Това ме накара да се чудя – може ли да се определи кога се изпълнява клауза от SQL заявка и колко често? Access има средство за показване на планове за изпълнение, но не влиза в подробности за това как и кога данните се обработват. Има заобиколен начин за извеждане на физическото поръчка за обработка, използвана от механизма на база данни на Access:персонализирана VBA функция!
Обществена функция Trace(име на събитие като низ, незадължителна стойност като вариант) като булева, ако липсва(стойност) Тогава Debug.Print EventName, "#No Value#" Else Debug.Print EventName, Value End Ако Trace =TrueEnd Functionпредварително>Това може да бъде записано в стандартен модул. След това можем да създадем проста таблица:
Проследяване на клаузите на заявка за достъп
С тази настройка можем да създадем заявка за достъп и да поръсим
Trace
в различни части на заявката за достъп. Ето един пример:SELECT c1.ColorID, Trace("SELECT") AS Ignored1, Trace("SELECT",c1.Color) AS Ignored2FROM tblColor AS c1 WHERE Trace("WHERE") <> 0 И Trace("WHERE", c1 .Color) <> 0ORDER BY Trace("ORDER BY"), Trace("ORDER BY", c1.Color);Ако след това отворите заявката в изглед на лист с данни, след което преминете към непосредствения прозорец на VBIDE, трябва да видите изхода по следния начин:
WHERE #No Value#ORDER BY #No Value#SELECT #No Value#WHERE RedORDER BY RedWHERE GreenORDER BY GreenWHERE BlueORDER BY BlueSELECT BlueSELECT GreenSELECT RedТова ни дава известна представа за това как Access разрешава заявката, което може да бъде полезно, когато трябва да оптимизирате заявка с лошо представяне. Нека видим какво можем да научим:
- Можем да видим, че ако няма препратки към колони, функцията VBA се извиква възможно най-рано, тъй като Access разпознава, че те могат да имат само една стойност за целия набор от резултати, така че няма смисъл да извиквате функцията отново и отново само за да получите същия отговор. Можете да видите, че
Trace
извикванията без 2-ри незадължителен аргумент се оценяват първо преди всички други извиквания, съдържащи препратка към колона във втория незадължителен аргумент. - Като следствие от предишната точка, ако извикването съдържа препратка към колона, тя трябва да бъде оценена поне веднъж за всеки ред. Можете да видите, че преминаваме през всяка стойност на цвят, когато оценяваме клаузата.
- Виждаме, че редът като цяло е подобен на този, който виждаме в диаграмата на Ицик Бен-Ган;
WHERE
се оценява възможно най-рано,ORDER BY
се оценява, след като елиминираме всички неквалифицирани редове, след което каквото и да е останало,SELECT
след това се оценява. - Въпреки че бихме очаквали сортирането да бъде приложено, след като сме филтрирали неквалифицирани редове, изглежда, че Access предпочита да опита да сортира изхода възможно най-скоро, вероятно защото е по-евтино да се вмъкне нов ред в сортирани списък над сортирането на целия набор.
Допълнителни експерименти и заключения
Можете да експериментирате малко с различна заявка. Например, можете да получите представа за това кога/често Access обработва GROUP BY
, като използвате заявка, подобна на тази:
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 ].[Цвят]) <> 0GROUP BY c1.ColorID, Trace("GROUP BY", c1.Color)ORDER BY c1.ColorID;
След това можете да използвате това във връзка с JetShowPlan, за да научите повече за това какво всъщност прави двигателят на базата данни. Надяваме се, че може да ви бъде полезен при получаването на представа за това как можете да подобрите ефективността на заявката си за достъп. Като предизвикателство бихте могли да обсъдите защо Access изпълнява GROUP BY
начина, по който го прави. Също така ви насърчавам да експериментирате при отваряне на лист с данни и превъртане. След това ще откриете, че SELECT
се преоценява в резултат на навигация.
Трябва да отбележа, че техниката по-горе ни дава представа за физическото план за обработка, а не логическия ред на обработка, както е описано в диаграмата. Съответно трябва да очакваме планът да бъде различен за различен обем данни или за различна заявка. Трябва също да вземем предвид, че добавянето на Trace
функция може да повлияе на плана. Въпреки това бих казал, че ако сте толкова загрижени за тези съображения, вероятно е по-добре да преместите тази заявка и основните й данни в база данни на SQL Server, където имате много повече възможности за оптимизиране на производителността на заявката.
Забавлявайте се!
Нуждаете се от помощ със заявки за Microsoft Access? Обадете се на експертите за достъп на (773) 809 5456 или изпратете имейл на екипа днес.