Файл: Хрусталева Е. Ю. Язык запросов 1С-Предприятия 8 (2013).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 12.03.2019

Просмотров: 51762

Скачиваний: 8724

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

получать выборки по частям с помощью оператора ПЕРВЫЕ, используя данные
последней полученной записи предыдущей выборки в качестве начального условия
при получении очередной выборки.

Не использовать запросы в цикле

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

Для решения данной задачи можно написать запрос к таблице остатков регистра
накопления ОстаткиНаСкладах и передать в качестве параметра в виртуальную
таблицу условие отбора по конкретному элементу номенклатуры. И затем выполнять
данный запрос в цикле для каждого элемента из массива номенклатуры. Это можно
сделать с помощью следующего запроса (листинг 4.6).

Листинг 4.6. Выполнение запроса для получения остатков номенклатуры в цикле – неправильный вариант

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

Поэтому такой фрагмент кода нужно переписать следующим образом (листинг 4.7):

Листинг 4.7. Выполнение запроса для получения остатков номенклатуры за один раз – правильный вариант


background image

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

Но иногда требуемое условие запроса, позволяющее отказаться от выполнения в цикле,
сформулировать бывает затруднительно или очень сложно. В этом случае как минимум
нужно вынести создание запроса за пределы цикла, а в цикле изменять только
параметры запроса. Это позволит избежать многократной синтаксической проверки текста
запроса (листинг 4.8).

Листинг 4.8. Выполнение запроса для получения остатков номенклатуры в цикле

Не использовать в запросе функции от параметров

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

Например, необходимо получить данные приходных накладных за определенный период.
Для этого можно выполнить следующий запрос (листинг 4.9).


background image

Листинг 4.9. Вывод документов «Поступление товаров» за определенный период – неправильный вариант

Казалось бы, все правильно – вся логика сосредоточена в одном месте. Но такой запрос
будет работать неоптимально, так как СУБД «не поймет», что в условии запроса
используется константа (значение параметра Дата).

Поэтому лучше сначала вычислить значение функции во встроенном языке и затем
передать его в запрос как параметр (листинг 4.10).

Листинг 4.10. Вывод документов «Поступление товаров» за определенный период – правильный вариант

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

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

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

Для решения данной задачи можно написать запрос к таблице остатков регистра
накопления ОстаткиНаСкладах и наложить условие отбора по конкретному элементу
номенклатуры в предложении ГДЕ (листинг 4.11).

Листинг 4.11. Выполнение запроса для получения остатков номенклатуры с условием отбора в предложении «ГДЕ» –
неправильный вариант


background image

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

Для оптимального выполнения подобного запроса следует ограничивать объем
выбираемых данных в самой виртуальной таблице. Поэтому такой фрагмент кода следует
переписать следующим образом (листинг 4.12):

Листинг 4.12. Выполнение запроса для получения остатков номенклатуры с условием отбора в параметре виртуальной
таблицы – правильный вариант

При этом не следует забывать о логике выполнения запроса. Например, в случае
накладывания условия отбора на виртуальные таблицы регистра сведений (СрезПервых,
СрезПоследних) оба рассмотренных выше варианта (накладывание условия отбора в
предложении ГДЕ или в параметре виртуальной таблицы) дадут разный результат, так
как в этих случаях прикладной смысл выполняемого запроса меняется.

подробнее

Подробнее этот вопрос рассмотрен в разделе "

Получение данных из периодических

регистров сведений

".

Соответствие индексов и условий запроса

Для построения оптимального плана запроса очень важно наличие подходящих индексов
в таблицах – источниках запроса по полям, которые используются в условиях запроса (в
предложении ГДЕ, в условии соединения таблиц ПО, в параметрах виртуальных таблиц, в
предложении ИМЕЮЩИЕ).

подробнее

Подробные рекомендации по эффективному использованию индексов рассматривались в
разделе «

Индексирование таблиц

».

Не использовать соединения с вложенными запросами и с виртуальными
таблицами

В запросах часто требуется получить данные из нескольких источников, связанных по


background image

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

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

При написании таких запросов нужно помнить, что соединение с вложенным запросом
может крайне замедлить выполнение запроса, сделать работу запроса нестабильной
(чувствительной к используемой СУБД и аппаратуре) и вообще является потенциально
опасным моментом для быстродействия системы.

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

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

В итоге получается довольно громоздкий и запутанный запрос (листинг 4.13).

Листинг 4.13. Выполнение запроса для получения остатков номенклатуры, содержащихся в документе, – неправильный
вариант