Для того, чтобы помочь вам оптимизировать производительность приложений, Visual FoxPro включает в себя технологию доступа к данным, называемую Оптимизация запросов Rushmore (Rushmore Query Optimization). Применяя технологию Rushmore, вы сможете выполнять определенные сложные табличные операции в сотни и даже тысячи раз быстрее, чем без нее.

Понимание технологии оптимизации запросов Rushmore

Технология оптимизации запросов Rushmore - это технический прием, который использует стандартные индексы Visual FoxPro для того, чтобы оптимизировать доступ к данным. Вы можете использовать Rushmore с любым индексом Visual FoxPro, включая индексы FoxPro 1.x (.idx), компактные (.idx) и составные индексы (.cdx).

Как .cdx- так и компактные .idx-индексы используют технический прием сжатия, при котором их размер становится равным одной шестой части несжатых индексов старого формата. Visual FoxPro может обработать сжатый индекс быстрее, поскольку требуется меньше времени на доступ к диску и большее число индексов будет буферизовано в памяти. Хотя оптимизация запросов Rushmore, подобно другим файловым методам доступа, извлекает преимущества из меньшего размера компактных индексов, она также хорошо работает и с индексами старых форматов.

Когда Visual FoxPro обрабатывает очень большие таблицы на компьютерах с самым минимальной объемом RAM, Rushmore не сможет работать из-за недостатка оперативной памяти. В этом случае, Visual FoxPro может отобразить предупреждающее сообщение "Not enough memory for optimization" ("Не достаточно памяти для оптимизации"). В этом случае, ваша программа хотя и будет функционировать правильно и без потери данных, но вы не получите пользы от оптимизации Rushmore при выполнении запросов.

В своей самой простой форме, Rushmore ускоряет выполнение одно-табличных команд, использующих предложения FOR (FOR clauses) для точного определения наборов записей с точки зрения существующих индексов. Кроме того, Rushmore может ускорять работу таких команд, как LOCATE и INDEX. Полный список оптимизируемых команд приведен в подразделе "Использование оптимизации запросов Rushmore при работе с таблицами".

SQL-команды Visual FoxPro используют Rushmore как основной инструмент оптимизации в многотабличном  запросе, применяя для этого существующие индексы и даже создавая новые, специально созданные для этого случая (ad-hoc), индексы, что позволяет ускорить выполнение запроса.

Использование оптимизации запросов Rushmore при работе с таблицами

Используйте Rushmore для оптимизации доступа к данным в зависимости от количества затрагиваемых при этом таблиц. Если вы работаете с одиночными таблицами, то можете получить выигрыш от применения Rushmore везде, где фигурирует предложение FOR. Если вы работаете с множеством таблиц, то запросы SELECT - SQL заменяют собой всю оптимизацию Rushmore. В команде SQL Visual FoxPro сам решает, что необходимо оптимизировать запрос, и делает всю работу за вас. Вам не нужно открывать таблицы или индексы. Если SQL решит, что ему нужны индексы, то он создаст временные индексы для своего собственного использования.

При использования оптимизации запросов Rushmore
  1. Для доступа к данным из одиночных таблиц применяйте предложение FOR в таких командах как AVERAGE, BROWSE или LOCATE, или используйте для обновления таблиц команды SQL. Полный список команд, в которых применяется предложение FOR, указан в таблице, приведенной ниже.

    или

  2. Для доступа к данным из более чем одной таблицы, применяйте команды SELECT - SQL, DELETE - SQL, и UPDATE - SQL.

Следующая таблица содержит команды, которые используют предложение FOR. Rushmore сконструирован таким образом, что скорость его работы прямо пропорциональна количеству извлекаемых записей.

Потенциально оптимизируемые команды с предложением FOR

AVERAGE

BLANK

BROWSE

CALCULATE

CHANGE

COPY TO

COPY TO ARRAY

COUNT

DELETE

DISPLAY

EDIT

EXPORT TO

INDEX

JOIN WITH

LABEL

LIST

LOCATE

RECALL

REPLACE

REPLACE FROM ARRAY

REPORT

SCAN

SET DELETED

SET FILTER

SORT TO

SUM

TOTAL TO

 

Если вы применяете в командах предложение scope (диапазон), то scope должна быть установлена в значения ALL (все) или REST (остальное), иначе от Rushmore не будет проку. Предложения NEXT (следующие) или RECORD (запись №...) блокируют Rushmore. Поэтому для большинства команд умалчиваемое значение scope всегда установлено в ALL и Rushmore будет работать когда вы пропускаете предложение scope.

Rushmore может использовать любые открытые индексы за исключением фильтрующих и UNIQUE (уникальных) индексов.

Замечание:
Для оптимального выполнения не устанавливайте порядок таблицы.

Создание индекса или тегов автоматически устанавливает порядок. Если Вы хотите получить от Rushmore максимальное преимущество при работе с большими наборами данных, которые должны быть определенным образом упорядочены, то выполните SET ORDER TO для того, чтобы отключить управление индексами, а затем выполните команду SORT.

Эффективная индексация для оптимизации запросов Rushmore

Rushmore не может воспользоваться всеми преимуществами индексов. Если вы применяете в команде INDEX предложение FOR, то Rushmore не сможет использовать этот индекс для оптимизации. Например, следующий оператор не может быть оптимизирован именно из-за использования в нем предложения FOR: INDEX ON ORDNUM FOR DISCOUNT > 10 TAG ORDDISC.

Кроме того, Rushmore не может использовать индекс, созданный с условием NOT. Например, это выражение может быть оптимизировано: INDEX ON DELETED() TAG DEL, а вот это - нет: INDEX ON NOT DELETED() TAG NOTDEL.

В том случае, когда вы хотите исключить из запроса удаленные записи, использование индекс, созданного в первом примере, ускорит операции, при условии, что вы установили SET DELETED в значение ON.

Работа без оптимизации запросов Rushmore

Операции поиска данных продолжаются без оптимизации Rushmore в следующих ситуациях:

  • Когда Rushmore не может оптимизировать выражения из предложения FOR в потенциально оптимизируемых командах.

  • Когда команда, которая может быть усилена применением Rushmore, содержит предложение WHILE.

  • Когда слишком мало памяти. Поиск данных продолжается, но без оптимизации.

Отключение оптимизации запросов Rushmore

Впрочем, иногда возникает необходимость в отключении Rushmore. Когда выполняется команда, оптимизированная по этой технологии, вначале определяется набор записей, отвечающих выражению предложения FOR. Только эти записи и будут обработаны командой.

Если потенциально оптимизируемая команда модифицирует индексный ключ в предложении FOR, то набор записей, с которым оперирует Rushmore, может стать неактуальным. Отключив Rushmore, вы гарантируете себе работу с самой свежей информацией из таблицы.

Чтобы отключить Rushmore для конкретной команды
  1. Примените предложение NOOPTIMIZE.

    Например, следующая команда LOCATE не оптимизируется:

      Копировать код
    LOCATE FOR DueDate < {^1998-01-01} NOOPTIMIZE

Вы можете глобально включить или отключить Rushmore для всех команд, получающих выгоду от Rushmore,  можно командой SET OPTIMIZE.

Для глобального отключения Rushmore
  1. Воспользуйтесь следующим кодом:

      Копировать код
    SET OPTIMIZE OFF
Для глобального включения Rushmore 
  1. Воспользуйтесь следующим кодом:

      Копировать код
    SET OPTIMIZE ON

По умолчанию оптимизация Rushmore установлена в ON.

Оптимизация выражений Rushmore

Технология Rushmore зависит от наличия в предложении FOR или в предложении SQL WHERE основного оптимизируемого выражения. Основное оптимизируемое выражение может составлять все выражение или его часть. А еще, вы можете скомбинировать основные выражения для того, чтобы сформировать составное оптимизируемое выражение.

Создание основных  оптимизируемых выражений

Основное оптимизируемое выражение принимает одну из двух следующих форм:

  Копировать код
 eIndex relOp eExp
      

или

  Копировать код
 eExpr relOp eIndex
      

Основное оптимизируемое выражение имеет следующие характеристики:

  • eIndex точно соответствует выражению на котором был создан индекс.

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

  • relOp это один из следующих реляционных операторов: <, >, =, <=, >=, <>, #, ==, or !=. Можно также воспользоваться функциями ISNULL( ), BETWEEN( ) или INLIST( ) (или их SQL-эквивалентами, такими как IS NULL и т.п.).

Можно использовать функции BETWEEN( ) or INLIST( ) в следующих двух формах:

  Копировать код
BETWEEN(eIndex, eExpr, eExpr)

или

  Копировать код
INLIST(eIndex, eExpr [, eExpr, eExpr, ...])
Замечание:
Функции ISBLANK() и EMPTY() не оптимизируются Rushmore.

Если вы создаете индексы firstname, custno, UPPER(lastname) и hiredate, то каждое из следующих выражений будет оптимизируем:

  Копировать код
firstname = "Fred"
custno >= 1000
UPPER(lastname) = "SMITH"
hiredate < {^1997-12-30}

Оптимизируемые выражения могут содержать переменные и функции, которые приводятся к определенному значению. Например, если используется индекс addr и вы дали команду STORE "WASHINGTON AVENUE" TO cVar, то следующие операторы так же являются основными оптимизируемыми выражениями:

  Копировать код
ADDR = cVar
ADDR = SUBSTR(cVar,8,3)

Осмысление того, когда запросы могут быть оптимизированы

Важно понимать когда запросы будут оптимизированы и когда не будут. Visual FoxPro оптимизирует условия поиска, отыскивая точное совпадение между левой стороной выражения фильтра и индексным ключевым выражением. Следовательно, Rushmore может оптимизировать выражение только в том случае, если вы ведете поиск точно по такому же выражению, которое применено в индексе.

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

  Копировать код
USE CUSTOMERS
INDEX ON UPPER(cu_name) TAG name

Следующая команда не оптимизируемая, потому что поисковое выражение основано на поле cu_name, а не на выражении индекса:

  Копировать код
SELECT * FROM customers WHERE cu_name ="ACME"

Поэтому вы должны создать оптимизируемое выражение, использующее команду, в которой поисковое выражение точно соответствует индексному выражению, а именно:

  Копировать код
SELECT * FROM customers WHERE UPPER(cu_name) = "ACME"
Совет:
Для того, чтобы определить уровень оптимизации Rushmore, используйте функцию SYS(3054).

Комбинирование основных оптимизируемых выражений

Вы можете комбинировать простые или сложные выражения, основанные на предложениях FOR  или WHERE для того, чтобы увеличивать скорость поиска данных, при условии, что FOR-выражения имеют характеристики основных оптимизируемых выражений.

Основные выражения могут быть оптимизируемыми. Вы можете скомбинировать выражения при помощи логических операторов AND, OR, and NOT для получения сложного выражения в предложении FOR, которое также может быть оптимизируемым. Если одно или больше основных выражений не оптимизируемые, то сложное выражение может быть частично оптимизируемым или совсемне оптимизируемым.

Инструкцией определено, что если выражение формировалось из основных оптимизируемых или неоптимизируемых выражений, то оно может быть полностью оптимизируемым, частично оптимизируемым, или не оптимизируемым. Следующая таблица суммирует в себе правила оптимизации запроса Rushmore.

Комбинирование основных выражений

Основное выражение Оператор Основное выражение Результат запроса

Оптимизируемое

AND

Оптимизируемое

Полностью оптимизируемый

Оптимизируемое

OR

Оптимизируемое

Полностью оптимизируемый

Оптимизируемое

AND

Не оптимизируемое

Частично оптимизируемый

Оптимизируемое

OR

Не оптимизируемое

Не оптимизируемый

Не оптимизируемое

AND

Не оптимизируемое

Не оптимизируемый

Не оптимизируемое

OR

Не оптимизируемое

Не оптимизируемый

NOT

Оптимизируемое

Полностью оптимизируемый

NOT

Не оптимизируемое

Не оптимизируемый

Вы можете применить оператор AND для комбинирования двух оптимизируемых выражений в одно полностью оптимизируемое выражение:

  Копировать код
FIRSTNAME = "FRED" AND HIREDATE < {^1997-12-30} && Оптимизируемое

В следующем примере оператор OR комбинирует основное оптимизируемое выражение с неоптимизируемым выражением, для получения не оптимизируемого выражения:

  Копировать код
FIRSTNAME = "FRED" OR "S" $ LASTNAME && Не оптимизируемое

Применение оператора NOT для оптимизируемого выражения создает полностью оптимизируемое выражение:

  Копировать код
NOT FIRSTNAME = "FRED" && Полностью оптимизируемое

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

Комбинирование сложных выражений

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

Комбинирование сложных выражений

Выражение Оператор Выражение Результат

Полностью оптимизируемое

AND

Полностью оптимизируемое

Полностью оптимизируемое

Полностью оптимизируемое

OR

Полностью оптимизируемое

Полностью оптимизируемое

Полностью оптимизируемое

AND

Частично оптимизируемое

Частично оптимизируемое

Полностью оптимизируемое

OR

Частично оптимизируемое

Частично оптимизируемое

Полностью оптимизируемое

AND

Не оптимизируемое

Частично оптимизируемое

Полностью оптимизируемое

OR

Не оптимизируемое

Не оптимизируемое

NOT

Полностью оптимизируемое

Полностью оптимизируемое

Частично оптимизируемое

AND

Частично оптимизируемое

Частично оптимизируемое

Частично оптимизируемое

OR

Частично оптимизируемое

Частично оптимизируемое

Частично оптимизируемое

AND

Не оптимизируемое

Частично оптимизируемое

Частично оптимизируемое

OR

Не оптимизируемое

Не оптимизируемое

NOT

Частично оптимизируемое

Не оптимизируемое

Не оптимизируемое

AND

Не оптимизируемое

Не оптимизируемое

Не оптимизируемое

OR

Не оптимизируемое

Не оптимизируемое

NOT

Не оптимизируемое

Не оптимизируемое

Вы можете скомбинировать полностью оптимизируемые выражения с помощью оператора OR для создания выражения, которое также будет полностью оптимизируемым:

  Копировать код
* Полностью оптимизируемое выражение
(FIRSTNAME = "FRED" AND HIREDATE < {^1997-12-30}) ;
OR (LASTNAME = "" AND HIREDATE > {^1996-12-30})

Для создания частично оптимизируемых выражений скомбинируйте полностью оптимизируемое выражение с неоптимизируемым с помощью оператора AND:

  Копировать код
* Частично оптимизируемое выражение
(FIRSTNAME = "FRED" AND HIREDATE < {^1997-12-30}) ;
AND "S" $ LASTNAME

Частично оптимизируемые выражения можно комбинировать для создания также частично оптимизируемого выражения:

  Копировать код
* Частично оптимизируемое выражение
(FIRSTNAME = "FRED" AND "S" $ LASTNAME) ;
OR (FIRSTNAME = "DAVE" AND "T" $ LASTNAME)

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

  Копировать код
* Не оптимизируемое выражение
("FRED" $ FIRSTNAME OR "S" $ LASTNAME) ;
OR ("MAIN" $ STREET OR "AVE" $ STREET)

См. также