Секция “Условия”: несколько причин медленного выполнения запросов
(4 видео)



Условия в запросах как причина медленной работы 1С

Наблюдаемая производительность 1С далеко не всегда определяется какими-то сложными серверными настройками или ограничениями “железа”.

Да, можно воткнуть в сервер еще 16Gb серверной памяти с коррекцией (сейчас она относительно недорога, 11-12 тысяч) – но вполне может оказаться, что это не окажет какого-либо значительного эффекта.

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

Собственно, об этом сегодняшние видео…

И это достаточно распространенная проблема.

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

И как только первый “похожий результат” получен – работа сразу же сдается (поскольку сроки уже горят).

В итоге возникают ситуации, когда запрос на тестовой базе работал быстро, а на реальной базе он приводит к “зависанию” всей системы.

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

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

Мы посмотрим, какие ошибки в секции “Условия” запроса снижают скорость его исполнения (и зачастую – серьезнейшим образом).

Видео 01:

Применение ИЛИ в запросах - делаем так, чтобы запрос повесил систему

Применение ИЛИ в запросах – как сделать так, чтобы через некоторое время запрос “повесил” систему

Логическое ИЛИ часто встречается в решении задач, в том числе при выборе данных с помощью запроса.

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

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

Видео 02:

О вреде использования математических вычислений в условиях запроса

О вреде использования математических вычислений в условиях запроса

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

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

Видео 03:

Использование отрицаний в запросах - НЕ В, НЕ, НЕ ПОДОБНО

Использование отрицаний в запросах – НЕ В, НЕ, НЕ ПОДОБНО, <>

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

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

Видео 04:

Непопадание в индекс при использовании встроенных функций языка запросов

Непопадание в индекс при использовании встроенных функций языка запросов

В видео показано, к чему приводит использование встроенных функций языка запросов в условиях.

Разобраны 2 примера для функций работы с датами и строками. Также показаны способы оптимизации таких запросов.

Смотрите еще:

Курс по технической настройке 1С и повышению стабильности.

Ускорение и оптимизация систем на 1С:Предприятие 8.3
Подготовка к 1С:Эксперт по технологическим вопросам

Поддержка – 3 месяца. Объем курса – 35 учебных часов.

Не откладывайте свое обучение!

55 комментариев к “Секция “Условия”: несколько причин медленного выполнения запросов
(4 видео)

  1. Дмитрий сказал:

    Ребят вы сначала свой сайт оптимизируйте чтоб страницы не висли при загрузке и перезагрузке.

    И главное пользователь вас будет вспоминать добрым слово при каждом обновлении не типовой когда получит счета :D

    • Татьяна Гужавина сказал:

      Дмитрий, если возникают проблемы с сайтом, пожалуйста, сообщите на support@kursy-po-1c.ru
      Уточните на каких именно страницах у Вас возникла проблема.

  2. Den сказал:

    Странно. Не удалось воспроизвести Index Scan (использовалось условие ИЛИ в предложении ГДЕ) на SQL Server 2008.

    Текст запроса:
    ВЫБРАТЬ
    БанковскиеКартыИСчета.Ссылка
    ИЗ
    Справочник.БанковскиеКартыИСчета КАК БанковскиеКартыИСчета
    ГДЕ
    (БанковскиеКартыИСчета.Ссылка = &Ссылка
    ИЛИ БанковскиеКартыИСчета.Ссылка = &Ссылка2)

    Так тоже бывает? Или я где то, что то сделал не так?

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

    • Андрей Бурмистров сказал:

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

      • Den сказал:

        Спасибо за ответ. Просто хотелось воспроизвести ситуацию. Получается такой вывод: “Если запрос работает быстро, то лучше ничего не трогать”.

        Но, конструкцию ИЛИ лучше не использовать. Ибо она может привести к скану.

        • Андрей Бурмистров сказал:

          > Если запрос работает быстро, то лучше ничего не трогать
          Это верно.

          Конструкцию ИЛИ надо использовать с осторожностью, это не значит что нужно совсем от нее отказаться, просто надо знать что иногда она может приводить к проблемам, в видео эти нюансы описаны.

  3. Roza Aleksey сказал:

    Здравствуйте, Андрей! Скажите, использование НЕ в секции ГДЕ понятно, а как насчет использования НЕ в параметрах виртуальных таблиц? Пример, у меня есть запрос к РБ ХозрасчетныйОборотыДтКт, где в условие кор. счетов стоит НЕ СчетКт В ИЕРАРХИИ (&Счет9009). Это считается хорошо для оптимизатора и можно/нужно этот момент как-нибудь дорабатывать? Спасибо!

    • Андрей Бурмистров сказал:

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

  4. Павел сказал:

    Добрый день. В Видео не увидел, как можно заменить условие В (&Таблица). Это возможно через левое соединение, наверно?

    • Андрей Бурмистров сказал:

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

    • Юлия Толстых сказал:

      Добрый день!
      Проверьте настройки безопасности в браузере, вероятно, блокируется запуск скрипта видеоплеера.

    • Насипов Фарит сказал:

      Видео на месте. Наводите мышь на картинку рядом с описанием и нажимайте.

      • geron4 сказал:

        Проверил на 2-х компьютерах, браузер Хром, нет картинок и самих ссылок, мышка тоже не может “нащупать” ссылку.

        • Татьяна Гужавина сказал:

          Проверьте настройки безопасности в браузерах — возможно, что они просто блокируют запуск скрипта видеоплеера.

      • Ober сказал:

        Добрый день! Видео не играет, вместо этого скачивается файл *.bin, как исправить?

        • Татьяна Гужавина сказал:

          Доброго дня, Марат!
          Видео доступно только для просмотра. Скачать не получится.

  5. alex.petrik83 сказал:

    Изменил запрос, как показано на видео, переделал из “НЕ Ссылка В (_ВременнаяТаблица)” в ” Левое Соединение … и ЕСТЬ NULL “, у меня запрос стал работать дольше, почти в 2 раза((((
    Строк 905…

    • Андрей Бурмистров сказал:

      Такое бывает но крайне редко, скорее всего и первоначальный запрос у вас работал достаточно быстро и индекс использовался. Если запрос работает быстро, то и переписывать его не нужно. Если переписанный запрос стал медленнее то скорее всего индекс по какой-то причине не используется, что бы разобраться нужна база и способ воспроизведения.

  6. Михаил сказал:

    А как насчет применения ИЛИ в параметрах виртуальной таблицы, это тоже нежелательно?
    Еще вопрос: Условие типа Таблица.Измерение ПустаяСсылка Тоже не сможет использовать индекс?
    И еще вопрос: Применение НЕ к булевым полям – не проблема? например Условие Не Документ.Проведен ни чем не отличается от Документ.Проведен = ложь?

    • Андрей Бурмистров сказал:

      > А как насчет применения ИЛИ в параметрах виртуальной таблицы, это тоже нежелательно?

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

      > Еще вопрос: Условие типа Таблица.Измерение ПустаяСсылка Тоже не сможет использовать индекс?

      Не понял что это за условие. Приведите пример такого запроса.

      > Применение НЕ к булевым полям — не проблема? например Условие Не Документ.Проведен ни чем не отличается от Документ.Проведен = ложь?

      Разницы не будет, текст запроса SQL и план запроса будут одинаковыми в обоих случаях.

      • Михаил сказал:

        Я имел ввиду условие
        Таблица.Документ Значение(Документ.Заказ.ПустаяСсылка)
        Условие тоже приводит к скану?

        • Андрей Бурмистров сказал:

          Само по себе такое условие к скану не приводит, но только если для этого поля есть соответствующий индекс.
          Здесь как и с любыми другими индексами многое зависит от того какие поля вы возвращаете в результате запроса. Если возвращаемые поля не входят в состав индекса, тогда может быть скан или Key Lookup (в зависимости от размера выборки).

  7. gosn1ck сказал:

    Добрый день.
    А если ли смысл вместо НЕ Проведён, использовать Проведен = Ложь в условиях запросов?

    • Андрей Бурмистров сказал:

      Разницы не будет, текст запроса SQL и план запроса будут одинаковыми.

  8. AveryanovAlexey сказал:

    По второму видео: Простые вычисления в условиях.
    Мои опыты в процессе прохождения 1 версии курса показали, что при использовании простых условий вроде:
    ГДЕ
    Числа.Число1 + 1 = 2
    вполне используется индекс (естественно, если Число1 проиндексировано). Мне показалось, что умный MSSQL сумел все-таки без проблем вычислить чему должно быть равно Число1.
    План запроса у меня был с Index Seek.

    А вот когда я использовал что-то посложнее, вроде:
    ГДЕ
    МЕСЯЦ(Числа.Дата1) = 12
    Вот тогда уже индекс не использовался и выполнялся честный Clustered Index Scan.

    Опыты проводил 8.3, MS SQL 2012

    • Андрей Бурмистров сказал:

      > План запроса у меня был с Index Seek.

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

      • AveryanovAlexey сказал:

        Андрей, снимаю перед вами шляпу!
        Я ошибся. Опыт не подтвердился. Видимо в прошлый раз я что-то напутал. Действительно всегда Index Scan, когда даже подобные простые условия ))

  9. Лекс Ливень сказал:

    Вопрос по второму видео.
    Условие
    Таблица.Число1+0 = 123
    Приводит к скану – это понятно.
    Но что будет, если вычисление перенести в правую часть?
    Таблица.Число1 = (123-0)
    По идее, здесь ведь оптимизатор может вычислить выражение, а потом прогнать по индексу?

    И замечание по первому примеру из Видео4. Условие МЕСЯЦ(Период)=8 выдаст движения за ВСЕ августы, любого года. А условие МЕЖДУ – только за август 2012-го.

    • Андрей Бурмистров сказал:

      > Но что будет, если вычисление перенести в правую часть?
      > Таблица.Число1 = (123-0)
      > По идее, здесь ведь оптимизатор может вычислить выражение, а потом прогнать по индексу?

      Все верно, эту ситуацию оптимизатор сразу распознает и здесь индекс используется.

      > И замечание по первому примеру из Видео4. Условие МЕСЯЦ(Период)=8 выдаст движения за ВСЕ августы, любого года. А условие МЕЖДУ — только за август 2012-го.

      Да это так, здесь основная цель – это показать что наложение функций на поле условие приводит к скану.
      Можно было бы написать условие «МЕСЯЦ(Период)=8 И ГОД(Период)=2012» смысл не меняется, все равно был будет скан.

      • Аноним сказал:

        В том то и вопрос, что если необходимо выбрать данные за все августы произвольного количества лет, то так просто заменить на условие МЕЖДУ не получается.

        • Андрей Бурмистров сказал:

          > если необходимо выбрать данные за все августы произвольного количества лет

          Тогда нужно сделать пакетный запрос или большой запрос с объедением, где в каждом из запросов буду выбираться данные за август одного года с использованием условия МЕЖДУ. В этом случае у вас не будет скана всей таблицы.

  10. Екатерина сказал:

    Добрый вечер!

    Хочу выразить огромную благодарность за материал! Ваши курсы помогают развиваться!

    После просмотра видео у меня возник вопрос: когда мы добавляем поле с заранее вычисленным значением, мы на это поле устанавливаем условие в этом же запросе?

    Пример 1.
    ВЫБРАТЬ
    Числа.Число1,
    Числа.Число2,
    Числа.Число1 / 1000 КАК ВычесленноеЗначение
    ИЗ
    РегистрСведений.Числа КАК Числа
    ГДЕ
    Числа.Число1 / 1000 = Числа.Число2

    Пример 2.
    ВЫБРАТЬ
    Числа.Число1,
    Числа.Число2,
    Числа.Число1 / 1000 КАК ВычесленноеЗначение
    ПОМЕСТИТЬ вт
    ИЗ
    РегистрСведений.Числа КАК Числа
    ;

    ////////////////////////////////////////////////////////////////////////////////
    ВЫБРАТЬ
    вт.Число1,
    вт.Число2,
    вт.ВычесленноеЗначение
    ИЗ
    вт КАК вт
    ГДЕ
    вт.ВычесленноеЗначение = вт.Число2

    Какой вариант правильнее использовать? Заранее спасибо за ответ!

    • Андрей Бурмистров сказал:

      Екатерина, здравствуйте.

      В данном случае оба варианта приведут к просмотру всей таблицы. Если не менять логику запроса, тогда здесь подойдет третий вариант: добавить в регистр новое измерение, проиндексировать его и заполнять при записи набора значений, вычисленным значением Числа.Число1 / 1000. После этого можно будет делать условие по этому полю на равенство без всяких вычислений.
      Если же задача узкоспециализированная и вам нужно проверять только условие «Числа.Число1 / 1000 = Числа.Число2», тогда можно сделать еще оптимальнее. Например, добавить измерение с типом «Булево» и при записи делать проверку, если «Числа.Число1 / 1000 = Числа.Число2» тогда реквизит будет равен значению «Истина», иначе «Ложь».

  11. Севостьянов Андрей сказал:

    Добрый день!
    Жду анонс курса по производительности.

        • Евгений Гилев (Мастер-тренер) сказал:

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

          • qwed сказал:

            Тоже приобретал прошлый курс, с нетерпение жду анонса данного курса, автор курса профи, видно не одну собаку съел в вопросах производительности.

  12. Светлана сказал:

    Почему перестали выкладывать файлы записей, нет возможности скачать видео, а потом смотреть его офф-лайн на планшете… печально

    • Насипов Фарит сказал:

      На этот сервис завязаны механизмы статистики.
      Закроем год – начнем выкладывать на YT.

  13. ProkopyukIN сказал:

    По первому видео. Так получается “В” вообще не рекомендуется использовать? Как такой запрос оптимизировать, если не известно заранее количество переменных?

    • Андрей Бурмистров сказал:

      На эту тему в курсе есть отдельный урок с примером оптимизации.
      Обычно условие «В» проблем не вызывает, но бывает и так что из-за него запрос выполняется со сканом. В этом случае можно поместить список во временную таблицу и соединятся с ней внутренним соединением.

        • Андрей Бурмистров сказал:

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

      • Василий сказал:

        А как соединится внутренним соединением с виртуальной таблицей остатков?
        Или для виртуальных таблиц – использовать “В” – это единственное решение?

        • Андрей Бурмистров сказал:

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Мы используем файлы cookies, чтобы сделать сайт удобнее.
Продолжая просмотр сайта, Вы соглашаетесь с их использованием.
Подробнее