7.4 Для повышения скорости выполнения запроса с условием необходимо
Опубликовано: Обновлено:
❓ 7.4 Для повышения скорости выполнения запроса с условием (в случае, когда это не противоречит прикладной логике) необходимо:
📚 Документация
Заголовок раздела «📚 Документация»-
ИТС: Общие требования по разработке оптимальных запросов
-
ИТС: Язык запросов «1С:Предприятия 8» — Общие рекомендации при написании запросов
-
ИТС: Язык запросов «1С:Предприятия 8» — Использовать параметры виртуальных таблиц
🧠 Краткая теория
Заголовок раздела «🧠 Краткая теория»Общий принцип оптимизации — обрабатывать меньше данных
Заголовок раздела «Общий принцип оптимизации — обрабатывать меньше данных»Одна из базовых рекомендаций при написании запросов — стараться минимизировать объем выборки, то есть получать запросом только те данные, которые действительно нужны.
Например, если для решения задачи нужны остатки только по одной номенклатуре, желательно по возможности ограничить данные этой номенклатурой как можно раньше, а не выполнять лишнюю обработку данных, которые затем будут отброшены.
Но оптимизация — это не попытка любой ценой выполнить всю задачу одним запросом. Слишком сложный запрос может, наоборот, ухудшить ситуацию: оптимизатору СУБД становится сложнее выбрать эффективный план его выполнения.
Поэтому стандарты рекомендует:
📐 Стандарт разработки: #std729
- выбирать только необходимые данные;
- писать запросы и условия соединения как можно проще;
- особенно осторожно использовать подзапросы в соединениях;
- не использовать без необходимости большое количество источников — отдельно отмечаются запросы с более чем 5–7 таблицами;
- не строить запросы, размер результата которых может неограниченно расти вместе с информационной базой.
Для обработки потенциально неограниченного объема данных рекомендуется получать данные по частям (курсорный механизм):
- установить уникальный порядок сортировки;
- получить часть записей с помощью
ПЕРВЫЕ; - использовать данные последней полученной записи как начальное условие следующей выборки.
Что такое виртуальные таблицы
Заголовок раздела «Что такое виртуальные таблицы»Чтобы понять, почему место условия может влиять на производительность, сначала разберемся с виртуальными таблицами.
Данные информационной базы физически хранятся в таблицах базы данных. Но физические таблицы СУБД и таблицы, которые платформа предоставляет разработчику в языке запросов 1С, — не одно и то же.
Через язык запросов мы можем обращаться к данным прикладных объектов. Например:
- Справочники
- Документы
- Табличные части
- Регистры
Например, к данным справочника можно обратиться так:
ИЗ Справочник.Номенклатура КАК Номенклатураа к записям регистра накопления:
ИЗ РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладахПри этом физическая структура хранения данных платформы значительно шире.
Например, регистр накопления использует не только таблицу движений, но и таблицу итогов. Однако напрямую обратиться к внутренней таблице итогов из языка запросов 1С разработчик не может.
Упрощенно:
Физические данные
информационной базы
│
┌───────────┴───────────┐
↓ ↓
Данные представлены Внутренние данные,
в языке запросов 1С к которым нет прямого
обращения из языка
запросов 1С
│ │
↓ ↓
Справочники Таблицы итогов
Документы Служебные таблицы
Регистры и другие внутренние
Табличные части структуры хранения
Но при решении прикладных задач нам как раз требуется получать рассчитанные данные — например, остатки или обороты регистра, — не разбираясь самостоятельно, из каких физических таблиц их необходимо получить.
Для этого платформа предоставляет виртуальные таблицы.
Что делает виртуальная таблица
Заголовок раздела «Что делает виртуальная таблица»Например, для регистра накопления могут быть доступны:
РегистрНакопления.ТоварыНаСкладах.ОстаткиРегистрНакопления.ТоварыНаСкладах.ОборотыРегистрНакопления.ТоварыНаСкладах.ОстаткиИОборотыВиртуальная таблица не является отдельной физической таблицей базы данных.
Можно воспринимать ее как предоставляемый платформой механизм получения определенного результата. Разработчик указывает виртуальную таблицу, а платформа формирует необходимое обращение к физическим данным информационной базы.
Например, при получении остатков платформа может использовать как таблицу итогов, так и таблицу движений регистра.
Упрощенно:
Запрос разработчика
РегистрНакопления.ТоварыНаСкладах.Остатки(...)
↓
1С
↓
┌────────────────┴────────────────┐
↓ ↓
Таблицы итогов Таблица движений
│ │
└────────────────┬────────────────┘
↓
Данные Остатки()
То есть разработчику не требуется самостоятельно определять, из каких физических таблиц и каким способом получить остаток. Эту работу выполняет платформа.
Виртуальную таблицу поэтому можно представить как своеобразный шаблон формирования запроса к физическим данным, но это именно упрощенная модель для понимания механизма, а не отдельная таблица, существующая в СУБД.
Где здесь появляется условие
Заголовок раздела «Где здесь появляется условие»Допустим, требуется получить остаток только по одной номенклатуре.
Можно написать условие в секции ГДЕ:
ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура.Наименование КАК Номенклатура, ТоварыНаСкладахОстатки.КоличествоОстатокИЗ РегистрНакопления.ТоварыНаСкладах.Остатки() КАК ТоварыНаСкладахОстаткиГДЕ ТоварыНаСкладахОстатки.Номенклатура = &НоменклатураВ этом случае условие из секции ГДЕ не участвует в формировании виртуальной таблицы. Сначала формируются данные виртуальной таблицы Остатки(), а затем к полученному результату применяется условие ГДЕ.
Упрощенно:
Таблицы базы данных
↓
Формирование виртуальной таблицы Остатки()
↓
Данные виртуальной таблицы
↓
ГДЕ
Номенклатура = &Номенклатура
↓
Результат
То есть с точки зрения логики запроса платформа сначала получает данные виртуальной таблицы, а затем выполняется отбор этих данных по условию ГДЕ.
Условие можно передать раньше
Заголовок раздела «Условие можно передать раньше»У виртуальной таблицы условие можно указать непосредственно в ее параметрах:
ВЫБРАТЬ ТоварыНаСкладахОстатки.Номенклатура.Наименование КАК Номенклатура, ТоварыНаСкладахОстатки.КоличествоОстатокИЗ РегистрНакопления.ТоварыНаСкладах.Остатки( , Номенклатура = &Номенклатура ) КАК ТоварыНаСкладахОстаткиТеперь платформа получает информацию об условии при формировании виртуальной таблицы.
Таблицы базы данных
↓
Номенклатура = &Номенклатура
↓
Платформа формирует данные Остатки()
↓
Результат
Именно поэтому в документации рекомендуется использовать параметры виртуальных таблиц вместо отбора в секции ГДЕ, когда это возможно.
Платформа получает условие раньше и может учитывать его при формировании обращения к данным виртуальной таблицы.
ГДЕ и ИМЕЮЩИЕ — это разные этапы отбора
Заголовок раздела «ГДЕ и ИМЕЮЩИЕ — это разные этапы отбора»Еще одно место, где хорошо виден принцип «отбрасывать ненужные данные раньше», — разница между секциями ГДЕ и ИМЕЮЩИЕ.
Обе конструкции задают условия, но применяются на разных этапах обработки данных.
ГДЕ отбирает записи до группировки.
ИМЕЮЩИЕ используется для отбора уже сгруппированных данных, то есть после вычисления группировок и агрегатных функций.
Например:
ВЫБРАТЬ Продажи.Номенклатура, СУММА(Продажи.Количество) КАК КоличествоИЗ РегистрНакопления.Продажи КАК ПродажиГДЕ Продажи.Склад = &СкладСГРУППИРОВАТЬ ПО Продажи.НоменклатураИМЕЮЩИЕ СУММА(Продажи.Количество) > 100Здесь выполняются два принципиально разных отбора:
Записи регистра
↓
ГДЕ Склад = &Склад
↓
Остаются записи нужного склада
↓
СГРУППИРОВАТЬ ПО Номенклатура
↓
Считается СУММА(Количество)
↓
ИМЕЮЩИЕ СУММА(Количество) > 100
↓
Остаются нужные группы
Условие по складу относится к исходным записям, поэтому оно может быть применено до группировки.
Условие СУММА(Количество) > 100 относится уже к результату группировки. До выполнения группировки такого значения еще нет, поэтому этот отбор выполняется через ИМЕЮЩИЕ.
| Конструкция | К чему применяется | Когда |
|---|---|---|
| Параметры виртуальной таблицы | К данным, формируемым виртуальной таблицей | При формировании виртуальной таблицы |
ГДЕ | К исходным строкам результата источников | До группировки |
СГРУППИРОВАТЬ ПО | Формирует группы и позволяет вычислить агрегаты | После отбора ГДЕ |
ИМЕЮЩИЕ | К результатам группировки | После группировки |
Логический порядок обработки запроса
Заголовок раздела «Логический порядок обработки запроса»Если собрать рассмотренные этапы вместе, упрощенную логическую последовательность можно представить так:
Источники данных
↓
Формирование виртуальных таблиц с учетом их параметров
↓
Соединение источников
↓
ГДЕ
отбор исходных записей
↓
СГРУППИРОВАТЬ ПО
формирование групп
↓
Вычисление агрегатных значений
↓
ИМЕЮЩИЕ
отбор полученных групп
↓
Формирование выбранных полей
↓
УПОРЯДОЧИТЬ ПО
↓
Результат запроса
Это логическая схема, помогающая понять смысл конструкций языка запросов. Она не означает, что СУБД обязана физически выполнять операции строго в такой последовательности: оптимизатор может преобразовывать план выполнения, сохраняя результат запроса.
Но именно такая модель хорошо показывает общий принцип оптимизации:
Параметры виртуальной таблицы
↓
ГДЕ
↓
СГРУППИРОВАТЬ ПО
↓
ИМЕЮЩИЕ
↓
Результат
Чем раньше можно корректно
исключить ненужные данные,
тем меньше данных требуется
обрабатывать дальше
Почему нельзя просто переносить любое условие
Заголовок раздела «Почему нельзя просто переносить любое условие»Из этого не следует, что любое условие нужно механически переносить на более ранний этап.
Каждая конструкция имеет собственный смысл:
- параметры виртуальной таблицы влияют на формирование ее данных;
ГДЕотбирает строки до группировки;ИМЕЮЩИЕотбирает результат группировки.
Перенос условия между этими этапами может изменить результат запроса.
Именно поэтому рекомендация по оптимизации применяется только тогда, когда более раннее наложение условия не противоречит прикладной логике.
Кроме того, само наличие условия еще не гарантирует одинаковый выигрыш в производительности. Необходимо учитывать структуру данных и возможность эффективного применения отбора.
Для регистров, в частности, имеет значение возможность эффективного использования условий отбора при обращении к данным. Эти особенности подробнее разберем дальше, в вопросах раздела «Оперативный учет».
В итоге здесь работает тот же общий принцип, с которого мы начали:
Нужна только часть данных
↓
Можно корректно исключить
ненужные данные раньше?
↓
Да
↓
Ограничиваем данные
как можно раньше
↓
Меньше данных участвует
в следующих операциях запроса
🧠 Ключевая мысль
Заголовок раздела «🧠 Ключевая мысль»При оптимизации запроса следует стремиться как можно раньше сократить объем обрабатываемых данных, не изменяя при этом прикладную логику. Условия виртуальной таблицы участвуют в формировании ее данных,
ГДЕотбирает записи до группировки, аИМЕЮЩИЕ— уже полученные группы.