Часть 3.При использовании индексов Fox осталась последняя проблема -
соединение нескольких таблиц по индексу.
Например, в результате подзапроса выбрали документы расходные накладные,
и хотелось бы присоединить их табличные части.
У Таблицы "Документ (Мн.ч.) РасходнаяНакладная" , как и у всех таблиц табличных частей
есть индекс
Цитата:I=IDLINE |of IDDOC+LineN
или в терминологии Fox
iddoc+STR(lineno,4)
Так как значение поля lineno неизвестно - соединиться с использованием индекса не удастся.
Особенно важно это для регистров , где таблица движений имеет индекс
Цитата:iddoc+STR(lineno,4)+STR(actno,6)
К счастью Fox позволяет выполнять соединение по части строк.
Но чтобы такое соединение заработало нужно выполнить код
ОлеДБКоманда = глОлеДБ.СоздатьКоманду();
ОлеДБКоманда.Выполнить("EXECSCRIPT('SET ANSI OFF')");
Наиболее подходящим местом которой - после создания объекта OLEDBData
Описание команды :
Цитата:SET ANSI ON | OFF
Параметры
ON
Короткие символьные строки дополняются справа пробелами или нуль-символами (0) для уравнивания их с более длинными символьными строками или выражениями. Когда SET ANSI установлено в ON, обе сравниваемые символьные строки должны иметь одинаковую длину.
OFF
(По-умолчанию) Определяет, что короткие символьные строки не дополняются справа пробелами или нуль-символами (0) в целях уравнивания длин сравниваемых строк. Когда SET ANSI установлено в OFF, две символьные строки сравниваются символ за символом по достижению конца короткой строки.
Т.е. это нужно учесть, если есть запросы, где могут использоваться поля разной длины
(для выборок полей это невозможно) Если в запросе вдруг понадобится все таки использовать полное
сравнение достаточно вместо "=" писать "==" (двойное сравнение)
После этого легко соединяться по индексу, для этого в левой части
выражения соединения (после ON) должно идти полное выражение индекса, а справа -
выражение по которому соединяемся
Пример
|SELECT
| ДокРасходнаяНакладная.Iddoc
| ,$ТаблЧастьРасходнаяНакладная.Товар
|
| FROM
|
| $Документ.РасходнаяНакладная as ДокРасходнаяНакладная
|
| LEFT JOIN $ДокументСтроки.РасходнаяНакладная as ТаблЧастьРасходнаяНакладная
| ON асходнаяНакладная.Iddoc
|
| WHERE ДокРасходнаяНакладная.iddoc =:ВыбРасход
|
// Используется 2 индекса
// 1. в секции Where - iddoc в таблице журнала
// 2. в секции JOIN - iddoc+STR(lineno,4) индекс таблицы ДокументСтроки.РасходнаяНакладная
Итого : время выполнения 0.002с
В секции JOIN есть строка
Цитата:ТаблЧастьРасходнаяНакладная.iddoc+STR(ТаблЧастьРасходнаяНакладная.lineno,4) = ДокРасходнаяНакладная.Iddoc
(Здесь плюсы - строковое сложение)
Т.к. стоит установка ANSI OFF то левое выражение будет обрезано до размера правого выражения ,
т.е. до ТаблЧастьРасходнаяНакладная.iddoc. Таким образом, это условие полностью эквивалентно -
Цитата:ТаблЧастьРасходнаяНакладная.iddoc=ДокРасходнаяНакладная.Iddoc
, а дополнение после "+" пишется только для того, чтобы Fox понял что нужно использовать индекс.
При
|LEFT JOIN $ДокументСтроки.РасходнаяНакладная as ТаблЧастьРасходнаяНакладная
| ON ТаблЧастьРасходнаяНакладная.iddoc=ДокРасходнаяНакладная.Iddoc
Время выполнения 0.129с
Разница 50 раз. При многопользовательском режиме еще больше.
Т.е. грубо говоря, можно придерживаться следующего простого правила :
для того, чтобы Fox использовал индекс нужно
составить обычный запрос - как для SQL ,
но только в предложениях WHERE, JOIN - левое выражение дополнять до индекса, который хотим использовать.
И предварительно задать SET ANSI OFF Можно проверить - оптимизирован ли Ваш запрос для выполнения vfpoledb.
Для этого получаем текстовый вид запроса для Fox :
Цитата:глМД = СоздатьОбъект("MetaDataWork");
ТекстЗапросаДляFoxPro=глМД.ОбрМетаСКЛ(ТекстЗапроса);
Выполняем. Если запрос оптимизирован в отдельном окне будет написано Rushmore optimization FULL
или соотвественно NONE