Эффективный доступ к данным – рекомендации
Следующие рекомендации предназначены, чтобы помочь Вам улучшить производительность запросов. Это только рекомендации, и при определенных обстоятельствах Вы можете игнорировать некоторые из них. В любом случае, следует обязательно проанализировать листинг перекрестных ссылок Xref и, при необходимости, реальное использование индексов по таблицам VST. Такой анализ еще более необходим, если проблема производительности реально существует при эксплуатации приложения.
Дизайн БД и правила индексирования
- Индексная обработка, включая, например, вычисление word-индекса, происходит на стороне OpenEdge сервера, а клиенту возвращается только необходимый минимум записей.
- Поскольку количество удовлетворяющих запросу записей практически всегда меньше общего количества записей, необходимо тщательно проектировать индексированный доступ.
- Добавление дополнительных индексов к таблице имеет как преимущества, так и недостатки. Преимущества: увеличение скорости чтения записей из БД. Недостатки: увеличение времени на создание, удаление и изменение записи в БД.
- Используйте меньше индексов для часто обновляемых таблиц, и больше индексов для часто читаемых, но менее часто обновляемых таблиц.
- Так как наличие индексов приводит к увеличению времени на обработку таблицы, то неиспользуемые индексы можно удалить. Для анализа можно использовать XREF и VST таблицу _indexstat. При анализе следует учитывать, что некоторые индексы могут использоваться для поддержки уникальности записей.
- При компиляции с использованием XREF выражение WHOLE-INDEX не всегда означает обработку всех записей таблицы, например выражения FIND FIRST и т.п. выдают в листинг WHOLE-INDEX, но реально выполняются очень быстро.
- При анализе XREF листинга следует обращать внимание и на сортировку выборок (записи SORT-ACCESS в листинге). Если сортировка выполняется часто и по большим выборкам, имеет смысл добавить соответствующий индекс.
Программирование условий выбора
- Избегайте соединений с парами диапазона с помощью AND.
- Избегайте OR в запросах FIND, если хотя бы одно из выражений разделенных OR не использует индекс (или все его компоненты). OpenEdge будет вынужден сканировать все записи, используя первичный индекс. Если все выражения внутри OR индексированы и их кол-во определено, то в запросах FOR и QUERY использовать конструкции с OR целесообразно. Для того, чтобы избавится от OR выражений в WHERE можно использовать, например, циклы.
- Избегайте выражений WHERE, которые с помощью OR связывают word-индекс и неиндексированный критерий (WHERE comments CONTAINS “computer” OR address2 = “Bedford”)
- Порядок условий в WHERE не имеет значения.
- USE-INDEX – старайтесь по возможности избегать, так как это лишает ABL возможности использования нескольких индексов для оптимизации запроса.
- Существуют различные механизмы улучшения брэкетинга, например перебор диапазонов возможных значений, использование временных таблиц, замена операторов <>, более гибкое использование конструкции (IF/THEN/ELSE).
- Что лучше, использовать один многокомпонентный индекс или несколько простых индексов? Ответ на этот вопрос зависит от конкретного приложения, но в случае использования всех компонентов многокомпонентного индекса доступ по нему гарантировано лучше, чем по нескольким простым индексам.
- WORD-индексы включаются при использовании оператора CONTAINS (ни BEGINS, ни BY не используют WORD-индексы). Причем для оператора CONTAINS всегда требуется использование WORD-индекса. Использование WORD индекса влияет на выполнение запроса в RUN-TIME. Так XREF может показывать использование нескольких индексов в запросе, тогда как в зависимости от выражения CONTAINS, реально может использоваться только один.
Некоторые особенности чтения записей
- Чтение записи RECID/ROWID не требует индекса для доступа к записи.
- Как известно, FOR сбрасывает последнюю обработанную запись при выходе из блока по END. Но из этого правила есть несколько исключений:
LEAVE – преждевременный выход из блока
BREAK BY – читает две записи
FIRST/LAST – читает первую/последнюю запись.
В этих случаях запись доступна (AVAILABLE) после окончания блока FOR. - FIND без опций FIRST/LAST выполняет уникальный поиск, что приводит к двум запросам к БД, следует избегать для увеличения производительности.
- PRESELECT – формирует RESULT LIST, что приводит к некоторым задержкам при выполнении запроса, но последующее обращение к записям в запросе не вызывает задержек.
- Опция BY для операторов FOR FIRST/LAST дает непредсказуемый результат, поэтому правильно использовать FOR EACH/LEAVE.
- Функция CAN-FIND выполняется на стороне клиента, поэтому не может использоваться сервером для индексного поиска. Следует избегать CAN-FIND в WHERE выражениях.
- Использование OPEN-QUERY с оператором DEFINE BROWSE делает доступной первую запись из выборки.
- Функция NUM-RESULST возвращает кол-во записей в RESULT LIST.
- Оператор OPEN-QUERY не требует заранее определять выборку через DEFINE.
- Если запись заблокирована, GET EXCLUSIVE-LOCK NO-WAIT делает запись доступной c NO-LOCK статусом, при этом функция LOCKED возвращает TRUE.
- Выполнение OPEN QUERY EXCLUSIVE не влияет на блокировку записей до их чтения.
- GET и FIND могут использовать совместно один и тот же буфер, но не один индексный курсор. Необходимо избегать совместного использования этих операторов по одному буферу, может привести к трудно разрешимым ошибкам.
- REPOSITION – всегда использует RESULT LIST, не читает запись, указывает на место между записями. Может реально быть проблемой в случае использования в запросах без INDEXED-REPOSITION (с мульти-индексами).