Наблюдаемая производительность 1С далеко не всегда определяется какими-то сложными серверными настройками или ограничениями “железа”.
Да, можно воткнуть в сервер еще 16Gb серверной памяти с коррекцией (сейчас она относительно недорога, 11-12 тысяч) – но вполне может оказаться, что это не окажет какого-либо значительного эффекта.
В то же время можно в разы ускорить документы и отчеты, просто заглянув в код…
Собственно, об этом сегодняшние видео…
И это достаточно распространенная проблема.
Часто при написании запросов разработчик стремится просто как можно быстрее выполнить задачу в соответствии с постановкой.
И как только первый “похожий результат” получен – работа сразу же сдается (поскольку сроки уже горят).
В итоге возникают ситуации, когда запрос на тестовой базе работал быстро, а на реальной базе он приводит к “зависанию” всей системы.
И что самое неприятное – это может проявиться не сразу после обновления, а в разгар следующего дня, когда пользователи начнут уже по полной эксплуатировать систему.
В этих видео мы покажем несколько причин медленной работы запросов с реальным объемом данных, а также способы их ускорения.
Мы посмотрим, какие ошибки в секции “Условия” запроса снижают скорость его исполнения (и зачастую – серьезнейшим образом).
Применение ИЛИ в запросах – как сделать так, чтобы через некоторое время запрос “повесил” систему
Логическое ИЛИ часто встречается в решении задач, в том числе при выборе данных с помощью запроса.
Однако использование этого оператора в запросах содержит ряд подводных камней.
О том, какие он может вызывать проблемы и как их решить, расскажем в данном видео.
О вреде использования математических вычислений в условиях запроса
Безобидная вещь – использование математических функций – может стать причиной медленной работы запроса.
В этом уроке рассмотрим пример, когда оптимизатор СУБД выбирает неоптимальный план выполнения запроса из-за обычной операции сложения.
Использование отрицаний в запросах – НЕ В, НЕ, НЕ ПОДОБНО, <>
Многие задачи по выборке данных решаются с помощью проверки того, что нужные элементы не входят в некоторый список (это зачастую подзапрос). И такие запросы становятся проблемой, когда данные в ИБ накапливаются, поскольку СУБД их не может эффективно выполнять.
В видео показано, почему такая проблема возникает и как ее решить.
Непопадание в индекс при использовании встроенных функций языка запросов
В видео показано, к чему приводит использование встроенных функций языка запросов в условиях.
Разобраны 2 примера для функций работы с датами и строками. Также показаны способы оптимизации таких запросов.
Смотрите еще:
Курс по технической настройке 1С и повышению стабильности.
Поддержка – 3 месяца. Объем курса – 35 учебных часов.
Не откладывайте свое обучение!
Доброго дня!
Видео 4 сейчас тоже недоступно. Можете починить?
Видео поправили. Обновите страницу.
Спасибо большое)
Видео 4 сейчас недоступно. Можете починить?
Благодарим за сообщение! Доступ к видео поправили.
Ребят вы сначала свой сайт оптимизируйте чтоб страницы не висли при загрузке и перезагрузке.
И главное пользователь вас будет вспоминать добрым слово при каждом обновлении не типовой когда получит счета :D
Дмитрий, если возникают проблемы с сайтом, пожалуйста, сообщите на support@kursy-po-1c.ru
Уточните на каких именно страницах у Вас возникла проблема.
Странно. Не удалось воспроизвести Index Scan (использовалось условие ИЛИ в предложении ГДЕ) на SQL Server 2008.
Текст запроса:
ВЫБРАТЬ
БанковскиеКартыИСчета.Ссылка
ИЗ
Справочник.БанковскиеКартыИСчета КАК БанковскиеКартыИСчета
ГДЕ
(БанковскиеКартыИСчета.Ссылка = &Ссылка
ИЛИ БанковскиеКартыИСчета.Ссылка = &Ссылка2)
Так тоже бывает? Или я где то, что то сделал не так?
На других таблицах, в т.ч. содержащих несколько миллионов записей, также не удалось воспроизвести. Всегда был Index Seek.
Ничего странного. Условие ИЛИ для ссылочных типов может приводить к скану, но это не значит что обязательно приведет.
Спасибо за ответ. Просто хотелось воспроизвести ситуацию. Получается такой вывод: “Если запрос работает быстро, то лучше ничего не трогать”.
Но, конструкцию ИЛИ лучше не использовать. Ибо она может привести к скану.
> Если запрос работает быстро, то лучше ничего не трогать
Это верно.
Конструкцию ИЛИ надо использовать с осторожностью, это не значит что нужно совсем от нее отказаться, просто надо знать что иногда она может приводить к проблемам, в видео эти нюансы описаны.
Не забывайте главное правило “Работает – не лезь”
Совершенно верно.
Здравствуйте, Андрей! Скажите, использование НЕ в секции ГДЕ понятно, а как насчет использования НЕ в параметрах виртуальных таблиц? Пример, у меня есть запрос к РБ ХозрасчетныйОборотыДтКт, где в условие кор. счетов стоит НЕ СчетКт В ИЕРАРХИИ (&Счет9009). Это считается хорошо для оптимизатора и можно/нужно этот момент как-нибудь дорабатывать? Спасибо!
Если ваш запрос работает быстро и проблем не вызывает, тогда и дорабатывать ничего не нужно.
Если же запрос работает медленно именно из-за этого условия, тогда здесь надо подумать как его переписать, тут возможны несколько вариантов в зависимости от задачи. Использовать описанный прием здесь скорее всего не получится.
Добрый день. В Видео не увидел, как можно заменить условие В (&Таблица). Это возможно через левое соединение, наверно?
Можно сделать из списка временную таблицу и соединятся с ней внутренним соединением, это особенно актуально когда в списке много элементов.
В браузере Chromium (http://www.chromium.org/) видео не играет а качает bin файлы
Добрый день!
Проверьте настройки безопасности в браузере, вероятно, блокируется запуск скрипта видеоплеера.
Видео только мне недоступны? Не вижу ссылок.
Видео на месте. Наводите мышь на картинку рядом с описанием и нажимайте.
Проверил на 2-х компьютерах, браузер Хром, нет картинок и самих ссылок, мышка тоже не может “нащупать” ссылку.
Проверьте настройки безопасности в браузерах — возможно, что они просто блокируют запуск скрипта видеоплеера.
Добрый день! Видео не играет, вместо этого скачивается файл *.bin, как исправить?
Доброго дня, Марат!
Видео доступно только для просмотра. Скачать не получится.
Изменил запрос, как показано на видео, переделал из “НЕ Ссылка В (_ВременнаяТаблица)” в ” Левое Соединение … и ЕСТЬ NULL “, у меня запрос стал работать дольше, почти в 2 раза((((
Строк 905…
Такое бывает но крайне редко, скорее всего и первоначальный запрос у вас работал достаточно быстро и индекс использовался. Если запрос работает быстро, то и переписывать его не нужно. Если переписанный запрос стал медленнее то скорее всего индекс по какой-то причине не используется, что бы разобраться нужна база и способ воспроизведения.
А как насчет применения ИЛИ в параметрах виртуальной таблицы, это тоже нежелательно?
Еще вопрос: Условие типа Таблица.Измерение ПустаяСсылка Тоже не сможет использовать индекс?
И еще вопрос: Применение НЕ к булевым полям – не проблема? например Условие Не Документ.Проведен ни чем не отличается от Документ.Проведен = ложь?
> А как насчет применения ИЛИ в параметрах виртуальной таблицы, это тоже нежелательно?
Условие ИЛИ не то что бы не желательно, просто оно может приводить к проблемам, это не значит что от него вообще надо отказаться.
Все правила написания запросов относятся к параметрам виртуальных таблиц точно так же, как и ко всему остальному.
> Еще вопрос: Условие типа Таблица.Измерение ПустаяСсылка Тоже не сможет использовать индекс?
Не понял что это за условие. Приведите пример такого запроса.
> Применение НЕ к булевым полям — не проблема? например Условие Не Документ.Проведен ни чем не отличается от Документ.Проведен = ложь?
Разницы не будет, текст запроса SQL и план запроса будут одинаковыми в обоих случаях.
Я имел ввиду условие
Таблица.Документ Значение(Документ.Заказ.ПустаяСсылка)
Условие тоже приводит к скану?
Само по себе такое условие к скану не приводит, но только если для этого поля есть соответствующий индекс.
Здесь как и с любыми другими индексами многое зависит от того какие поля вы возвращаете в результате запроса. Если возвращаемые поля не входят в состав индекса, тогда может быть скан или Key Lookup (в зависимости от размера выборки).
Добрый день.
А если ли смысл вместо НЕ Проведён, использовать Проведен = Ложь в условиях запросов?
Разницы не будет, текст запроса SQL и план запроса будут одинаковыми.
А где найти такую консоль запросов?)
Данная консоль будет в материалах курса.
А какого курса? Разработка и оптимизация запросов?
Курса по оптимизации и ускорению 1С: http://курсы-по-1с.рф/ускорение-1с/
Понял. Спасибо!
По второму видео: Простые вычисления в условиях.
Мои опыты в процессе прохождения 1 версии курса показали, что при использовании простых условий вроде:
ГДЕ
Числа.Число1 + 1 = 2
вполне используется индекс (естественно, если Число1 проиндексировано). Мне показалось, что умный MSSQL сумел все-таки без проблем вычислить чему должно быть равно Число1.
План запроса у меня был с Index Seek.
А вот когда я использовал что-то посложнее, вроде:
ГДЕ
МЕСЯЦ(Числа.Дата1) = 12
Вот тогда уже индекс не использовался и выполнялся честный Clustered Index Scan.
Опыты проводил 8.3, MS SQL 2012
> План запроса у меня был с Index Seek.
Значит вы смотрели план другого запроса, не может данная конструкция использовать индекс ни в какой версии СУБД. Попробуйте повторить свой опыт.
Андрей, снимаю перед вами шляпу!
Я ошибся. Опыт не подтвердился. Видимо в прошлый раз я что-то напутал. Действительно всегда Index Scan, когда даже подобные простые условия ))
Вопрос по второму видео.
Условие
Таблица.Число1+0 = 123
Приводит к скану – это понятно.
Но что будет, если вычисление перенести в правую часть?
Таблица.Число1 = (123-0)
По идее, здесь ведь оптимизатор может вычислить выражение, а потом прогнать по индексу?
И замечание по первому примеру из Видео4. Условие МЕСЯЦ(Период)=8 выдаст движения за ВСЕ августы, любого года. А условие МЕЖДУ – только за август 2012-го.
> Но что будет, если вычисление перенести в правую часть?
> Таблица.Число1 = (123-0)
> По идее, здесь ведь оптимизатор может вычислить выражение, а потом прогнать по индексу?
Все верно, эту ситуацию оптимизатор сразу распознает и здесь индекс используется.
> И замечание по первому примеру из Видео4. Условие МЕСЯЦ(Период)=8 выдаст движения за ВСЕ августы, любого года. А условие МЕЖДУ — только за август 2012-го.
Да это так, здесь основная цель – это показать что наложение функций на поле условие приводит к скану.
Можно было бы написать условие «МЕСЯЦ(Период)=8 И ГОД(Период)=2012» смысл не меняется, все равно был будет скан.
В том то и вопрос, что если необходимо выбрать данные за все августы произвольного количества лет, то так просто заменить на условие МЕЖДУ не получается.
> если необходимо выбрать данные за все августы произвольного количества лет
Тогда нужно сделать пакетный запрос или большой запрос с объедением, где в каждом из запросов буду выбираться данные за август одного года с использованием условия МЕЖДУ. В этом случае у вас не будет скана всей таблицы.
Добрый вечер!
Хочу выразить огромную благодарность за материал! Ваши курсы помогают развиваться!
После просмотра видео у меня возник вопрос: когда мы добавляем поле с заранее вычисленным значением, мы на это поле устанавливаем условие в этом же запросе?
Пример 1.
ВЫБРАТЬ
Числа.Число1,
Числа.Число2,
Числа.Число1 / 1000 КАК ВычесленноеЗначение
ИЗ
РегистрСведений.Числа КАК Числа
ГДЕ
Числа.Число1 / 1000 = Числа.Число2
Пример 2.
ВЫБРАТЬ
Числа.Число1,
Числа.Число2,
Числа.Число1 / 1000 КАК ВычесленноеЗначение
ПОМЕСТИТЬ вт
ИЗ
РегистрСведений.Числа КАК Числа
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
вт.Число1,
вт.Число2,
вт.ВычесленноеЗначение
ИЗ
вт КАК вт
ГДЕ
вт.ВычесленноеЗначение = вт.Число2
Какой вариант правильнее использовать? Заранее спасибо за ответ!
Екатерина, здравствуйте.
В данном случае оба варианта приведут к просмотру всей таблицы. Если не менять логику запроса, тогда здесь подойдет третий вариант: добавить в регистр новое измерение, проиндексировать его и заполнять при записи набора значений, вычисленным значением Числа.Число1 / 1000. После этого можно будет делать условие по этому полю на равенство без всяких вычислений.
Если же задача узкоспециализированная и вам нужно проверять только условие «Числа.Число1 / 1000 = Числа.Число2», тогда можно сделать еще оптимальнее. Например, добавить измерение с типом «Булево» и при записи делать проверку, если «Числа.Число1 / 1000 = Числа.Число2» тогда реквизит будет равен значению «Истина», иначе «Ложь».
Добрый день!
Жду анонс курса по производительности.
Скоро :)
Участникам прошлого курса “плюшки” будут?
Да, как раз сейчас думаем над спец. условиями для старых участников.
Думаю, что будет чем Вас порадовать. Детали сообщим чуть позже :)
Тоже приобретал прошлый курс, с нетерпение жду анонса данного курса, автор курса профи, видно не одну собаку съел в вопросах производительности.
Почему перестали выкладывать файлы записей, нет возможности скачать видео, а потом смотреть его офф-лайн на планшете… печально
На этот сервис завязаны механизмы статистики.
Закроем год – начнем выкладывать на YT.
По первому видео. Так получается “В” вообще не рекомендуется использовать? Как такой запрос оптимизировать, если не известно заранее количество переменных?
На эту тему в курсе есть отдельный урок с примером оптимизации.
Обычно условие «В» проблем не вызывает, но бывает и так что из-за него запрос выполняется со сканом. В этом случае можно поместить список во временную таблицу и соединятся с ней внутренним соединением.
в динамических списках это не прокатывает:(
Да в динамических списках есть определенные ограничения, именно поэтому там не рекомендуется делать сложных условий.
Надо понимать что условие «В» это не всегда плохо, это может привести к замедлению, но не значит что приведет.
Когда оптимизировать запрос в динамическом списке не получается, стоит подумать над тем, что бы сделать отдельную форму с обычной таблицей и с фильтрами для пользователя, тогда можно будет строить текст запрос динамически в зависимости от выбранных фильтров и избежать ограничений динамического списка. Например, в базах где одновременно работают тысячи пользователей динамические списки используются крайне редко.
А как соединится внутренним соединением с виртуальной таблицей остатков?
Или для виртуальных таблиц – использовать “В” – это единственное решение?
Ничто не мешает соединяться с виртуальной таблицей остатков, другое дело что это может привести к замедлению.
Все зависит от того какую задачу вы решаете, можно и В использовать, можно и с вирт. таблицей соединяться, можно и временную таблицу использовать, решение надо рассматривать в контексте конкретной задачи.