Оптимизация: неэффективные запросы

13.06.19

Разработка - Запросы

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

Пример №1

"ВЫБРАТЬ 
... ИЗ ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ ... ИЗ)"

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

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

Пример 2

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

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

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

"Но ведь все работает и так!" - спросят многие. Да, действительно, выполнив запрос, соединив его после левым соединением с нужным нам запросом, СУБД безусловно отбросит все лишние записи. Но это произойдет потом, а вначале она варварски заблокирует всю таблицу. А если это какой-то распухший и важный как Масленица регистр, ну, скажем, ОстаткиТоваров? А если у нас 100 пользователей одновременно работают в 1С и каждый в той или иной степени вынужден обращаться к данному регистру?

Думаю, тут все понятно.

Пример 3

Индексы и условия запроса.

Использование неиндексируемых полей в условиях запроса приводит к избыточному чтению данных СУБД и, как следствие, захвату гораздо большего количества записей, чем необходимо. Каждая читаемая запись в СУБД блокируется для чтения. 

Пример 4

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

"ВЫБРАТЬ
        Контрагенты.ОсновнойДоговор.Ссылка КАК ОсновнойДоговор
ИЗ
        Справочник.Контрагенты
ГДЕ
        Контрагенты.Родитель.Ссылка = &ТакиеТоКонтрагенты"

Казалось бы, чего тут такого - запрос как запрос. Ну подумаешь, дописываем мы везде, где в голову взбредет через точку Ссылка, чего тут такого? Зато - так нагляднее!

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

Проведем аналогию с яблоками: в магазине, если вы хотите купить одно яблоко, и вы знаете, что оно лежит в верхней раскрытой коробке, лежит на самом верху, вы не будете для этого вынимать все коробки с яблоками, потрошить их и раскладывать яблочки по одному, сравнивая их, пока не дойдете до нужной коробки и не выберете свое яблоко. Вы посмотрите несколько в той, что наверху, распакована и содержит уже подходящие вам яблоки. Так же и в СУБД: при обращении в запросе к полям таблицы через точку - вы заставляете систему строить подзапрос к таблице поля. 

И все бы ничего, но при чтении результатов запросса из СУБД, все записи, которых коснулся запрос будут заблокированы, и, для сохранения прикладной логики, никто не сможет ими в это время воспользоваться. 

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

Чтобы этого избежать, следует всегда помнить о главном правиле при построении запросов:

Все записи, которых коснется СУБД, будут заблокированы

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта Платформа 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    184726    1029    403    

968

Обновление 1С Запросы Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Абонемент ($m)

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

2 стартмани

06.02.2025    2200    17    XilDen    26    

36

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

В статье приведена удобная возможность отладки исполняемого запроса динамического списка.

03.12.2024    5733    artemusII    11    

23

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    13140    sergey279    18    

66

Запросы Программист Платформа 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    8220    XilDen    36    

90

СКД Механизмы типовых конфигураций Запросы Программист Платформа 1С v8.3 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Россия Бесплатно (free)

Работая с типовыми отчетами в конфигурациях «Зарплата и управление персоналом, редакция 3», «Зарплата и кадры государственного учреждения, редакция 3» и подобных, в схемах компоновки данных можно встретить конструкции запросов, которые обращаются к некоторым виртуальным таблицам.

20.08.2024    3192    PROSTO-1C    0    

23

Запросы Программист Запросы Бесплатно (free)

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

16.08.2024    10801    user1840182    5    

29