Вложенный запрос или временная таблица что лучше 1с
Зачастую нужно заранее сделать выборку из базы данных по некоему условию. Для этого в 1С 8.3 необходимо использовать вложенные запросы.
Но следует учитывать, что в большинстве случаев вложенные запросы в 1С бесполезны без соединения их результата с другими таблицами. Такое соединение практически в любом случае приведет к сильному замедлению выполнения запроса в целом.
Пример вложенного запроса на языке запросов
Приведу пример вложенного запроса на языке запросов 1С. Допустим, нам нужно сделать выборку суммы некоторого остатка по отдельным клиентам на определенную дату:
ВЫБРАТЬ
НераспОплатыОстатки.Заказчик,
НераспОплатыОстатки.СуммаОст
ИЗ(ВЫБРАТЬ
Заказчики.Ссылка КАК СсылкаНаСпрЗаказчики
ИЗ
Справочник.Заказчики КАК Заказчики
ГДЕ
Заказчики.Ссылка В(&Заказчики)) КАК ВложЗапросЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления. НераспОплаты.Остатки КАК НераспОплаты
ПО ВложЗапрос.СсылкаНаСпрЗаказчики = НераспОплатыОстатки.Заказчик
Когда СУБД будет выполнять такой запрос, не исключены неверные действия оптимизатора, так как трудно определиться с планом обработки запроса. Когда СУБД соединяет две таблицы, оптимизатор строит алгоритм на основе вычисления количества записей в этих таблицах.
Когда же используется вложенный запрос, вычислить количество записей, вернувшихся из вложенного запроса, очень трудно.
Как лучше?
Именно поэтому фирма 1С крайне не рекомендует использовать вложенные запросы, а вместо них разработала временные таблицы. С использованием временных таблиц наш предыдущий запрос будет выглядеть так:
// Временная таблица
ВЫБРАТЬ
Заказчики.Ссылка КАК Заказчики
ПОМЕСТИТЬ табЗаказчики
ИЗ
Справочник.Заказчики КАК Заказчики
ГДЕ Заказчики.Ссылка В (&Заказчики)
;// Основной запрос
ВЫБРАТЬ
табКлиенты.Ссылка,
НераспОплатыОстатки.СуммаОст,
ИЗ
табЗаказчики КАК табЗаказчики
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.НераспОплаты.Остатки(
,
Заказчик В
(ВЫБРАТЬ
табЗаказчики.Заказчики
ИЗ
табЗаказчики)) КАК НераспОплатыОстатки
ПО табЗаказчики.Заказчики = НераспОплатыОстатки.Заказчики
Смотрите также видео-урок про вложенные запросы:
Если вы только начинаете программировать в 1С или просто хотите систематизировать свои знания — попробуйте Школу программирования 1С нашего друга Владимира Милькина. Пошаговые и понятные уроки даже для новичка с поддержкой учителя.
Попробуйте бесплатно по ссылке >>
Теперь оптимизатор знает заранее, сколько записей во временной таблице, и без труда оптимизирует алгоритм выполнения соединения таблиц.
Запросы 1С:Предприятие 8. Вложенные запросы
Вложенные запросы – это запросы, вызываемые другим, внешним, запросом. Они всегда заключаются в круглые скобки и им обязательно должен присваиваться псевдоним. Некоторые считают вложенный запрос аналогом временных таблиц, однако эти два инструмента имеют ряд отличий, которые мы рассмотрим в данной статье.
Вложенный запрос видит только себя, он не видит внешний запрос. Это значит, что нельзя, например, установить во вложенном запросе условие по значению поля внешнего запроса.
Большинство представленных запросов не имеют какой-либо ценности и могли бы быть выполнены проще. Они приведены только для иллюстрации механизма вложенных запросов.
Вложенные запросы могут использоваться в конструкции ИЗ:
В том числе в соединениях:
И в условиях запроса со сравнением В или В ИЕРАРХИИ:
При этом количество выбираемых полей вложенного запроса должно соответствовать количеству операндов в левой части выражения В или В ИЕРАРХИИ.
Существует мнение, что вложенные запросы в сложных конструкциях выполняются платформой 1С нерационально, требуют бОльших ресурсов и времени, нежели те же самые запросы, выполненные иначе, без использования вложенных запросов. Однако в ряде случаев, обойтись без вложенных запросов невозможно.
Вместе с тем, обычно эффективнее работает один большой запрос с вложенными, чем последовательность запросов из модуля.
Практически всегда альтернативой вложенному запросу является использование временных таблиц. Этот инструмент имеет ряд преимуществ:
- Запрос становится более структурированным, его легче читать.
- Результат, загруженный во временную таблицу можно использовать несколько раз, и при этом нет необходимости заново выполнять запрос, чтобы этот результат получить. А вложенный запрос будет каждый раз выполняться заново, излишне загружая ресурсы системы.
Подведем итог: вложенные запросы лучше всего применять в достаточно простых конструкциях, при этом использовать их стоит только тогда, когда по-другому задачу не решить; в сложных запросах лучше использовать временные таблицы.
Запросы 1С:Предприятие 8. Вложенные запросы : 1 комментарий
Вложенные запросы
Рассмотрим, что такое вложенные запросы в языке запросов 1С и для чего они нужны.
Часто встречается ситуация, когда над таблицей необходимо проделать несколько последовательных действий. Достаточно показательным является пример, когда сначала надо сгруппировать данные, а потом уже на сгруппированную таблицу наложить некоторое условие, либо соединить с другой таблицей. В таких случаях на помощь и приходят вложенные запросы.
Вложенный запрос практически ничем не отличается от обычного запроса. Он заключается в скобки и в нем доступны почти все методы и функции языка запросов 1С. А для вышестоящего запроса доступны все поля вложенного запроса.
Структура самого примитивного вложенного запроса выглядит следующим образом
Конечно же в таком виде использование вложенного запроса не имеет смысла, т.к. можно сразу выбрать необходимые поля без использования вложенности. Здесь все предельно упрощено для простоты понимания.
А теперь рассмотрим все вышесказанное на примере.
Пусть у нас есть таблица СотрудникиПодразделений:
Подразделение | Сотрудник |
---|---|
Бухгалтерия | Иванов |
Администрация | Петров |
Бухгалтерия | Сидоров |
И мы хотим выбрать из этой таблицы все подразделения, где работает более одного сотрудника.
Первым шагом нам необходимо подсчитать количество сотрудников в каждом подразделении. Для этого сгруппируем исходную таблицу с использованием агрегатной функции КОЛИЧЕСТВО.
Если выполнить этот запрос, то в результате получим следующую таблицу
Подразделение | КоличествоСотрудников |
---|---|
Бухгалтерия | 2 |
Администрация | 1 |
Вторым шагом нам необходимо наложить на эту таблицу ограничение по количеству сотрудников. Для этого сделаем вышеприведенный запрос вложенным и в вышестоящем запросе пропишем соответствующее условие
Таким образом результат итогового запроса будет следующим
Подразделение |
---|
Бухгалтерия |
Справедливости ради стоит отметить, что тот же результат можно достигнуть с помощью функции ИМЕЮЩИЕ языка запросов 1С, а также с использованием временных таблиц.
На практике вы конечно же столкнетесь с более сложными вложенными запросами в которых может использоваться как соединение, так и объединение таблиц. А также может быть несколько уровней вложенности.
В некторых случаях можно реализовать запрос с временными таблицами а можно с вложенными запросами. Что быстрее выполняется? В каком случае оптимальнее используется память?
(1) newborn, этот вопрос тянет на докторскую. Если база на сиквеле, то там хотя бы можно сделать оба варианта и посмотреть профайлером план выполнения запросов и попробовать из него что-то узнать. Если база файловая, то тайну могут теоретически знать разработчики 1с, но я немного сомневаюсь, что кто-то может ответить на этот вопрос в общем без всякой конкретики.
Всё зависит от.
Иногда временные таблицы быстрей, иногда вложенные запросы.
Нужно проверять на конкретных базах, конкретных данных и конкретном железе.
Хотя 1с не рекомендует использовать вложенные (не смогли написать оптимизатор?)
(2) DenisCh,
Кстати, у меня вложенные работают очень неплохо. Я как-то ранее просто не задумывался над этой проблемой, пока не увидел, что то, что я делал на вложенных запросах, другой программист делал на временных таблицах.
(4) newborn, из опыта вложенные чаще бывают быстрей, но иногда лучше пожертовать скоростью в угоду удобочитаемости, а то сами же и не разберётесь через год что и как оно делает.
1C рекомендует пакетные запросы с временными таблицами.
От себя добавлю, что если запрос громоздкий, выполнение в виде временных таблиц часто повышает читаемость.
На самом деле всё зависит от конкретной задачи. Нельзя утверждать со 100% гарантией что во всех случаях быстрее то или это. Я пишу всё на временных таблицах, мне так удобнее их читать и разрабатывать(хотя иногда приходится делать через вложенные, по причине скорости).
Вложенные запросы могут точно так же быстро(а в некоторых случаях и быстрее отрабатывать). Так же временные таблицы хорошо использовать когда идет частое обращение к виртуальной таблице (отобрал 1 раз всё во временную таблицу, а потом крутишь её как хочешь).
На дисках ИТС - есть специальный раздел, посвященный оптимизации запросов :)
В общем случае лучше использовать временные таблицы, тогда улучшается читаемость запросов, появляется возможность многократного использования полученного результата, в большинстве случаев работа со временными таблицами происходит быстрее.
Простые вложенные запросы при использование MS SQL версии могут выполняться быстрее - все-таки в MS SQL встроен оптимизатор выполнения запроса, который может соединить подзапросы быстрее чем если явно будет прописана выборка данных во временную таблицу. но иногда оптимизатор работает не правильно ;) и тогда запросы без временных таблиц - ну просто тормозят ;)
при использовании временных таблиц в громоздких запросах не надо забывать об индексации полей, участвующих потом в соединениях - это может существенно ускорить работу на больших выборках (а может и немного замедлить на маленьких).
Зачастую нужно заранее сделать выборку из базы данных по некоему условию. Для этого в 1С 8.3 необходимо использовать вложенные запросы.
Но следует учитывать, что в большинстве случаев вложенные запросы в 1С бесполезны без соединения их результата с другими таблицами. Такое соединение практически в любом случае приведет к сильному замедлению выполнения запроса в целом.
Пример вложенного запроса на языке запросов
Приведу пример вложенного запроса на языке запросов 1С. Допустим, нам нужно сделать выборку суммы некоторого остатка по отдельным клиентам на определенную дату:
ВЫБРАТЬ
НераспОплатыОстатки.Заказчик,
НераспОплатыОстатки.СуммаОст
ИЗ(ВЫБРАТЬ
Заказчики.Ссылка КАК СсылкаНаСпрЗаказчики
ИЗ
Справочник.Заказчики КАК Заказчики
ГДЕ
Заказчики.Ссылка В(&Заказчики)) КАК ВложЗапросЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления. НераспОплаты.Остатки КАК НераспОплаты
ПО ВложЗапрос.СсылкаНаСпрЗаказчики = НераспОплатыОстатки.Заказчик
Когда СУБД будет выполнять такой запрос, не исключены неверные действия оптимизатора, так как трудно определиться с планом обработки запроса. Когда СУБД соединяет две таблицы, оптимизатор строит алгоритм на основе вычисления количества записей в этих таблицах.
Когда же используется вложенный запрос, вычислить количество записей, вернувшихся из вложенного запроса, очень трудно.
Как лучше?
Именно поэтому фирма 1С крайне не рекомендует использовать вложенные запросы, а вместо них разработала временные таблицы. С использованием временных таблиц наш предыдущий запрос будет выглядеть так:
// Временная таблица
ВЫБРАТЬ
Заказчики.Ссылка КАК Заказчики
ПОМЕСТИТЬ табЗаказчики
ИЗ
Справочник.Заказчики КАК Заказчики
ГДЕ Заказчики.Ссылка В (&Заказчики)
;// Основной запрос
ВЫБРАТЬ
табКлиенты.Ссылка,
НераспОплатыОстатки.СуммаОст,
ИЗ
табЗаказчики КАК табЗаказчики
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.НераспОплаты.Остатки(
,
Заказчик В
(ВЫБРАТЬ
табЗаказчики.Заказчики
ИЗ
табЗаказчики)) КАК НераспОплатыОстатки
ПО табЗаказчики.Заказчики = НераспОплатыОстатки.Заказчики
Смотрите также видео-урок про вложенные запросы:
Если вы только начинаете программировать в 1С или просто хотите систематизировать свои знания - попробуйте Школу программирования 1С нашего друга Владимира Милькина. Пошаговые и понятные уроки даже для новичка с поддержкой учителя.
Попробуйте бесплатно по ссылке >>
Теперь оптимизатор знает заранее, сколько записей во временной таблице, и без труда оптимизирует алгоритм выполнения соединения таблиц.
Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):
В чем ключевое различие между вложенными запросами и временными таблицами в 1С. Преимущества и недостатки этих способов.
Добавить комментарий Отменить ответ
Оснащение для магазина с доставкой от компании Ru-Holod
Выбор оборудования зависит от цели его эксплуатации. В магазине оборудование для реализации продуктов питания, условия хранения которых требуют поддержания особой .
Проверка отчетности 6-НДФЛ и 2-НДФЛ в 1С ЗУП 3.1
Какие проверки необходимо произвести для успешной сдачи отчетов 6-НДФЛ и 2-НДФЛ и какие средства в 1С ЗУП 3.1 в этом .
Как сократить издержки в производственной компании малого бизнеса. Вебинар
18 февраля 2020 г. состоялся вебинар «Как сократить издержки в производственной компании малого бизнеса. Планирование, фактическая себестоимость, анализ в 1С:Управление .
Интервью с Сергеем Кукановым
На предприятии есть производство, но вы ещё не доросли до крупных систем управления? Тогда вполне можете попробовать обойтись решением 1С:Управление .
В этом вопросе были рассмотренны различия между CTE (common table expresion) и подзапросами.
Но хотелось бы конкретизировать вопрос. При каких обстоятельствах каждый из следующих подходов более производителен?
- CTE
- Подзапрос
- Временная таблица
- Табличная переменная
Часто пользовался хранимыми процедурами, так как они выглядят более читабельными, чем множество вложенных подзапросов. Не рекурсивные CTE очень хорошо инкапсулируют наборы данных и тоже очень удобочитаемы.
Но есть ли конкретные обстоятельства, когда можно сказать, что тот или иной подход всегда будет работать производительней? Или надо постоянно выбирать на ощупь из разных подходов, чтобы найти наиболее производительное решение?
PS
Недавно узнал, что с точки зрения производительности, временные таблицы являются хорошим первым выбором, поскольку они имеют связанную с ними статистику.
1 ответ 1
SQL является декларативным языком, а не процедурным языком. То есть, создается запрос SQL для описания желаемых результатов, но при этом движку SQL не указывается, как ему выполнить запрос.
Как правило, желательно, чтобы оптимизатор в движке SQL нашёл сам лучший план выполнения запроса. На разработку движка SQL уходит очень много человеко-лет, поэтому положитесь на многолетний опыт разработчиков, который они накопили выполняя эту работу.
Несомненно, бывают ситуации, когда план запроса не является оптимальным. В этом случае надлежит использовать хинты запроса, реструктурировать запрос, обновлять статистику, использовать временные таблицы, добавлять индексы и т.д., чтобы повысить производительность.
Теоретически производительность CTE и подзапросов должна быть одинаковой, поскольку оба предоставляют одинаковую информацию оптимизатору запросов. Одно из отличий состоит в том, что CTE, использованный более одного раза, можно легко идентифицировать и выполнить один раз, то есть результаты могут быть сохранены и прочитаны несколько раз. К сожалению это не всегда так. SQL Server, например, не использует похоже преимущества этого базового метода оптимизации (назовём это общим устранением подзапроса).
Временные таблицы - это другое дело, потому что имеется больше информации о том, как должен выполняться запрос. Одно из основных отличий заключается в том, что оптимизатор может использовать статистику из временной таблицы для составления плана запроса. Это может привести к повышению производительности. Кроме того, если у вас есть сложный CTE (или подзапрос), который используется более одного раза, то сохранение его во временной таблице часто дает повышение производительности. Запрос выполняется только один раз.
И собственно ответ на вопрос заключается в том, что нужно попробовать различные варианты запроса, чтобы получить ожидаемую производительность, особенно для сложных запросов, которые выполняются на регулярной основе. Идеально было бы, чтобы оптимизатор SQL нашёл бы идеальный путь выполнения. Хотя это часто так и есть, но всегда остаётся возможность найти способ повысить производительность.
Читайте также: