Access. Программирование на VBA

Повышение скорости выполнения запросов


Оптимизация запросов в Jet — процесс довольно сложный, но это не значит, что в нем невозможно разобраться. Ниже приведены советы, которые помогут ускорить выполнение запросов:

• Рекомендуется создавать индексы для всех полей, которые будут использованы для определения критерия отбора.

Необходимо создавать индексы с обеих сторон связей в запросах.

• Вместо уникальных индексов лучше пользоваться начальными значениями. Поскольку начальные значения запрещают использование пулевых значений, запрос может использовать преимущества большего количества типов объединения.

• В результирующем наборе не следует отображать

какие-либо лишние столбцы. Обработка и отобра­жение каждого столбца занимает дополнительное время.

• Рекомендуется воздерживаться от употребления сложных выражений в запросах.

• Следует избегать функции IIF() (немедленное IF). IIF() оценивает и истинное, и ложное значения перед тем, как выдать результат. Если выполнять данную операцию для каждой записи, это может сильно повлиять на производительность.

• При использовании вложенных запросов рекомендуется записывать все вычисления в последнем запросе серии.

• Вместо Count([Customer]) лучше применять Count(*),

поскольку при срочной оптимизации Count(*) обрабатывается быстрее — перед подсчетом не нужно проверять нулевые значения.

• По возможности следует пользоваться оператором Between для уменьшения количества строк в ре­зультирующем наборе вместо операторов "больше чем" и "меньше чем".

• Обычно размещение условия со стороны "один" отношения "один-ко-многим" — самый эффектив­ный способ, но не всегда. Можно попробовать передвинуть ограничение к стороне "многие", что­бы проверить, не изменится ли производительность. После каждого изменения условий отбора необходимо тщательно проверять результирующий набор.



• Нормализованные таблицы могут хранить данные с использованием меньшего количества страниц данных и страниц индекса. Нормализация должна стать правилом, и нарушать ее можно лишь при отсутствии другой альтернативы.




• Рекомендуется по возможности поэкспериментировать с подчиненными запросами вместо исполь­ зования объединений или сложных условий OR. Оптимальный выбор зависит от многих дискретных факторов, и только эксперимент поможет решить, какой подход использовать.

• Внешние связи следует использовать только при крайней необходимости, поскольку они автомати­чески требуют проведения сканирования доминантной (сохраняемой) таблицы в объединении.

• Вместо SQL-операторов в коде рекомендуется использовать сохраненные запросы с параметрами. Jet уже скомпилировал запросы с параметрами и создал для них план выполнения (хотя эти планы не­доступны в SHOWPLAN.OUT). Использование скомпилированных и сохраненных запросов устраняет необходимость оценки и оптимизации SQL-строки. Access компилирует SQL-строки, использующиеся в качестве источника записей или источника строк для форм, отчетов или элементов управления, поэтому они остаются нетронутыми.

• Рекомендуется всегда использовать скомпилированные запросы.

• Для манипуляций с данными вместо DAO по возможности следует пользоваться запросами. Для решения этих задач запросы (SQL) всегда выполняются быстрее, чем DAO.

• Типы наборов записей следует выбирать с осторожностью. Если необходимо добавить или отре­дактировать данные, требуется динамическое множество. Снимок или однонаправленный снимок данных может понадобиться в том случае, когда необходимо только считать данные. Снимки доль­ше открываются, но прокручиваются быстрее.

• При открытии набора записей только для добавления данных следует использовать опцию dbAppendOnly.

При этом строки не считываются.

• При использовании данных клиент/сервер необходимо тестировать запросы к серверу. Кроме того, рекомендуется ознакомиться с новыми возможностями Access 2000, имеющими отношение к архи­тектуре клиент/сервер. Запросы к серверу не всегда выполняются быстрее, чем запросы к вложен­ным серверным таблицам, но сетевой трафик при их использовании меньше.

• Большие запросы действия могут выполняться лучше, если присвоить свойству UseTransaction зна­чение False. При проведении транзакций Access создает временные файлы. Иногда эти таблицы ста­новятся слишком большими и уменьшают скорость выполнения запросов.



• При запрашивании данных с сервера необходимо применять методы CacheStart, FillCache и EndCache для

обработки данных, поступающих с сервера.

• При работе с серверными данными следует избегать локальной обработки. Локальная обработка напоминает использование сложного выражения Group By с ключевым словом Distinct,

использо­вание оператора LIKE в текстовых полях или полях заметок, множественных агрегирующих функ­ций в перекрестном запросе или перекрестных запросов без условий ORDER.

Кроме того, следует избегать сложных внешних и внутренних комбинаций связей. Такие конструкции вынуждают сервер посылать громадные объемы данных на локальный PC для обработки, что значительно снижает производительность.

• Необходимо регулярно сжимать базу данных и проверять статистические показатели, используемые механизмом Jet для оптимизации запросов.

• Если это возможно, следует заполнить приложение таким же количеством тестовых данных, кото­рое будет использоваться при работе с пользователями. Механизм Jet сможет оптимизировать зап­росы, используя те статистические показатели, которые точно отражают реальные условия выполнения запросов.

• Рекомендуется индексировать поля для сортировки.

• Если данные являются в основном статичными, следует рассмотреть возможность создания таблич­ного запроса к необходимым данным вместо неоднократного запрашивания базы данных.

• Необходимо избегать использования доменных агрегирующих функций (DIookupO) для таблиц, кото­рых нет в запросе.

Запросы представляют собой наиболее сложный аспект Access. К счастью, большую часть работы по оптимизации запросов выполняет механизм Jet. Информация, изложенная в данном разделе, поможет разработчику оказать механизму Jet содействие при оптимизации. Следует проверить результаты экспери­ментов в SHOWPLAN и с помощью подпрограмм PrintStats и QueryTimer,

чтобы определить, какая комбинация решений выполняется с максимальной производительностью.


Содержание раздела