Компилятор запросов 1С 7.7

Компилятор запроса 0.6

КомпиляторЗапросов.zip

Описание:

Данная разработка предназначена для оптимизации работы стандартного объекта 1С «Запрос» (далее — 1СЗапрос).

Всем известно, что 1С77 считает MSSQL продолжением FoxPro.

При выполнении запроса, Предприятие вначале закачивает всю информацию к клиенту, а затем производит необходимые вычисления. Т.е. возможности SQL сервера практически не используются.

ТЗапрос выполняет эту работу. Перед выполнением он компилирует текст запроса в текст TransactSQL, и выполняет его на сервере, а клиенту передает только результат, что, собственно, и требуется. Причем работа ТЗапроса полностью аналогична работе 1СЗапроса, т.е. для уже написанных программ потребуется только заменить слово Запрос на ТЗапрос и все! Отличия от 1СЗапроса даны ниже. Кстати, ТЗапрос заметно расширяет возможности 1СЗапроса. Детали — в разделе ДОПОЛНЕНИЯ.

Не смотря на то, что программа написана на языке 1С, скорость ее работы практически не уступает скорости работы 1СЗапроса (замеры производительности даны в конце описания).

Требования:

  • 1С Предприятие 7.7
  • 1С++ от OXY.
  • Microsoft SQL Server (на DBF не работает)
  • Компонента «Оперативный учет» (т.к. поддерживаются только Справочник, Документ и Регистр).
  • С дугой компонентой (зарплата, бухучет) можно использовать только Справочник и Документ.

Установка:

  • Установить 1С++
  • Скопировать в каталог базы папку classes.
  • Скопировать файл functions.sql в корневой каталог базы. (При обновлении со старой рекомендуется запустить в QueryAnalyser скрипт update.sql)
  • Скопировать текст файла ГлобальныйМодуль.ert в глобальный модуль.
  •  Добавить в файл defcls.prm строку: //#include «classes\hpp.Запрос.ert»
  •  В каждом регистре поставить галочку «Быстрая обработка движений». Кстати, это повысит общее быстродействие конфигурации.
  •  Не забудьте для пользователей в меню Сервис->Параметры->1С++ выбрать «Оптимизация» и убрать «Проверка типов» и «Отладчик»

Использование:

Полностью аналогично применению стандартного Запроса 1С, отличия только в символе «Т»:

Вместо:

Надо писать:

Обращение к атрибутам производится так:

ВНИМАНИЕ! Переменные, используемые в запросе должны быть глобальными в контексте вызова!

 

ОТЛИЧИЯ

  1. Операторы запроса не чувствительны к регистру. Переменные чувствительны к регистру!
  2. В редких случаях порядок записей при сортировке может не совпадать с сортировкой Запроса 1С
  3. Логика sql — запроса работает лучше, чем логика Запроса 1С. Поэтому результаты в специфических ситуациях могут отличатся.

Например:

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

Или, к примеру, если в запросе по регистрам отсутствуют функции НачОст и т.п., то, по идее, результатом не должно быть пустое значение. Поэтому 1СЗапрос дает NULL, а правильный ТЗапрос дает не нулевой результат.

  1. Вместо функции запроса Запрос.ЭтоГруппа() используется переменная запроса, например:

  1. В функциях макс(n,n,…) и мин(n,n,…) допускается не более 5 значений.
  2. Нельзя использовать уточняющие переменные в функциях и условиях, определяйте все необходимые переменные заранее.
  3. ГРУППЫ справочника всегда сортируются по алфавиту, не зависимо от сортировки, указанной в Группировке.

 

Особенности:

  1. Пока нельзя использовать переменные типа Перем1=Документ.ПрихНакл.ЧтоТо,Документ.РасхНакл.ЧтоТо;

или

Корневой объект метаданных должен совпадать у всех переменных. Это будет что-то из разряда UNION ALL.

  1. Не работают периодические реквизиты.
  2. Не работает обратная группировка Запрос.Группировать(1,-1);
  3. Методы Запрос.ИспользоватьГрафуОтбора(ГрафаОтбора), Запрос.Получить() не реализованы.
  4. Проверка соответствия типов в условиях и функциях плохо работает на агрегатных типах. Будьте внимательны.

 

ЗАМЕЧАНИЯ

  1. Для справочника нельзя писать условие (ЭтоГруппа=0), надо (ЭтоГруппа<>1)
  2. Нельзя использовать служебные качестве имен переменных (напр. Группировка,Счётчик,Строка,Дата,Число).
  3. Справочники в условиях «В». ВАЖНО: Порядок переменных имеет значение. Слева от условия должны стоять внутренние переменные. Значение справа может быть любым. Но нельзя использовать значения функций в качестве аргументов выражений. Пример:

Надо заметить, что в подобных условиях имеет смысл только выражение ?(,,) :

Причем типы данных обоих результатов операции ?(,,) должны полностью совпадать.

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

  1. Переменные в выражении могут быть либо ВСЕ группировками/агрегатными функциями, либо все — нет. Например:

 

ДОПОЛНЕНИЯ

  1. можно сделать упорядочивание с любой глубины, например Группировка Товар упорядочить по Товар.БазоваяЕдиница.Наименование
  2. Если перед выполнением запроса установить Запрос.ВключитьОтладку=n, где n=[1-3], то в сообщния будет выводится отладочная информация. Так же можно увидеть сгенерированный скрипт.
  3. Поддерживаются функции НачТик(Таймер) и КонТик(Таймер) для замера производительности.

Например:

  1. Запрос.ЗначениеГруппировки(Имя_Номер_Группировки) и Запрос.ЗначениеФункции(Имя_Номер_Функции) работают.
  2. Можно использовать следующие описания переменных, например:

  1. В функции поддерживаются выражения sql в формате sql(‘SQLExpression’,ТипРезультата), например

  1. Можно использовать расширенный вариант Функции, например:

Поддерживается трансляция всех стандартных функций из разделов:

[Синтаксис-помошник]

->[Встроенный язык]

->[Конструкции языка]

->[Функции/процедуры]

->[Математические]

->[Строковые]

->[Работа с датой]

->[Преобразование типов]

а также функция выбора по условию ?(,,) .

Поддерживаются все, кроме:

СтрЧислоВхождений;СтрКоличествоСтрок;СтрПолучитьСтроку;OemToAnsi;AnsiToOem;РабочаяДата;ПериодСтр;НачалоСтандартногоИнтервала;КонецСтандартногоИнтервала;

Все это (включая функции и условия) будет скомпилировано в TSQL и выполнено.

Прим: Преобразование типов из строки в дату производится только в формате ДД.ММ.ГГ

  1. Поддерживается группировка регистра остатков и всех документов по периоду Год, Квартал, Месяц, Неделя, День, Час, Минута, Секунда!

При использовании группировки по регистру, нельзя использовать функции НачОст() и КонОст().

Для использования, укажите в имени группировки переменную с объектом Регистр или Документ. Какой реквизит выбран (Фирма, Количество и т.д.) — не существенно, например:

  1. ВНИМАНИЕ! Спец. функция sql(,) считается агрегатной. Со всеми вытекающими.
  2. Можно использовать инструкцию «ВыбратьПервые» для вывода первых n записей, где n=Число/Переменная, аналогично значению TOP n в sql., т.е. результат будет: SELECT TOP 1000 … FROM …
  3. «Без Групп» работает правильно. Т.е. группировки будут работать, просто результат будет без итогов.
  4. Добавлена работа с реквизитами недоопределенного типа <<Документ>> и <<Справочник>>, например, если:

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

Такая же ситуация у типа <<Справочник>>.

Нужно учитывать, что подобное использование ТЗапроса снижает эффективность выполнения, т.к. необходимо вызвать дополнительный мини-запрос, и в конечном запросе появится еще один вложенный.

Общие реквизиты документа для типа <<Документ>> выбираются без потерь в производительности наравне с остальными реквизитами.

 

ПРОИЗВОДИТЕЛЬНОСТЬ

(2 группировки, 12728 записей, 2000МГц Athlon, 512Mb DDR, представлено время на обработку всех записей) версия 0.1:

  1. Запрос.Выполнить() по понятным причинам работает до 100 раз БЫСТРЕЕ.

Время компиляции запроса (10 переменных,  4 функции, 4 группировки, 2 условия) – 260 мс.

  1. Запрос.ПолучитьАтрибут() 320мс против 265, 1.2 раз медленнее.
  2. Запрос.Группировка() — 781мс против 517 мс., 1.51 раз медленнее. При обходе данных по «верхним» группировкам, разность скоростей растет, т.к. ТЗапрос использует только последовательный перебор записей.
  3. Полный цикл 2-й вложенности (по 2-м группировкам) с выводом строк в Таблицу 17300мс против 17013мс, т.е. итоговая общая потеря производительности в 1.01 раз.

ВСЕ СКОРОСТИ ПРИВОДЯТСЯ БЕЗ УЧЕТА ВРЕМЕНИ ВЫПОЛНЕНИЯ ЗАПРОСА Запрос.Выполнить()!!!