Курс по Оптимизации 1С — Занятие №5

В рамках этого занятия необходимо изучить следующие материалы.

Модуль 3. Причины медленной работы

    Глава 8. Анализ причин медленной работы и оптимизация системы

    • Описание операторов плана запроса
    • Чтение плана запроса
    • Признаки неоптимального плана запроса

К сожалению, у Вас недостаточно прав для дальнейшего просмотра.

Если Вы приобрели курс, но еще не активировали токен — пожалуйста, активируйте доступ по инструкциям, высланным на Ваш email после покупки.

Если Вы не залогинены на сайте — залогиньтесь, вернитесь на эту страницу и обновите ее.

Если Вы залогинены, у Вас активирован токен доступа, но Вы все равно видите эту запись — напишите нам на e-mail поддержки.

Комментарии / обсуждение (217):

  1. Kurs-Spec83

    Добрый день!

    Из видео про не оптимальность вложенных циклов в плане запроса.
    В nested loops приходит ведущая таблица в 2 млн. записей. А запрос к ведомой таблице выполняется 1970000 раз, то есть меньше, чем количество строк ведущей таблицы. Как такое возможно, ведь оператор должен был выполниться ровно 2 млн раз?

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

  2. Смирнов Евгений Алексеевич

    Добрый день
    Рассматривая эту строку http://joxi.ru/n2YnM5XFM3LaA6

    Я правильно понимаю что
    1) Универсальный отчет самый тормознытуй?
    2) Длительность запроса пользователей от 50 до 100 секунд?
    3) Если учесть что универсальный отчет типовой, то оптимизировать мы уж не можем ни чего?
    4) А если посмотреть на план запроса самого тяжелого (108 сек) http://joxi.ru/MAjGDlBSzWz8re то проблема в Нестед лупсах?

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

  3. Смирнов Евгений Алексеевич

    Добрый день
    Решил посмотреть на реальной базе свой корявый запрос =)
    Который выполнялся 15 секунд
    Вот его план http://joxi.ru/V2VaJK3fwL3jmv
    Скажите пжста,
    1) я вроде понимаю что нестед лупс тут вообще не должен быть ибо подается 75 000 и 3500 строк ?
    Я так понимаю причина в сравнении колонки Предполагаемое кол-во строк и Реальное ? То есть проблема в статистике?
    2) Но нестед лупс тут занимает всего 16,4 кост. Получается самый проблемный оператор это Хэш матч и Сортировка (2 и 3 строки сверху)
    3) Еще проблема с 18 строкой. Идет сканирование и возвращает 2 млн строк а он хотел вернуть 1 строку. Тоже видимо статика?
    4) Или вы видите тут другие проблемы?

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

      • Смирнов Евгений Алексеевич

        Представим что у меня нет запроса =)
        Я хочу попробовать проанализировать по плану =)

        Видимо вы правы про 18 строку
        Но почему у нее Кост 50 а у 1 и 2 строки по 180? Или кост это не «тяжесть» оператора?
        Тогда еще вопрос по 18 строке. Я правильно понял что он думает вернет 1 строку а возвращает 2 млн? Вопрос почему он так думает?

        • Андрей Бурмистров


          (текст комментария доступен только участникам Мастер-группы)

  4. Смирнов Евгений Алексеевич

    Добрый день
    Смотрю видео про зазоры в индексах
    на примере запроса:
    ВЫБРАТЬ
    ОстаткиТоваровОстатки.Товар,
    ОстаткиТоваровОстатки.КоличествоОстаток
    ИЗ
    РегистрНакопления.ОстаткиТоваров.Остатки(
    ,
    Товар = &Товар
    И Склад = &Склад) КАК ОстаткиТоваровОстатки

    Я уже поменял измерения как надо для оптимального запроса
    http://joxi.ru/p27Oj74HONo327

    НО
    в профайлере я все равно вижу конструкцию seek where

    1 1 |—Clustered Index Seek(OBJECT:([optimize1c].[dbo].[_AccumRgT22].[_AccumRgT22_ByDims_TRRR] AS [T2]), SEEK:([T2].[_Period]=[@P1] AND [T2].[_Fld20RRef]=[@P2] AND [T2].[_Fld19RRef]=[@P3]), WHERE:(([optimize1c].[dbo].[_AccumRgT22].[_Fld21] as [T2].[_Fld21]CONVERT_IMPLICIT(numeric(16,0),[@P4],0)) AND ([optimize1c].[dbo].[_AccumRgT22].[_Fld21] as [T2].[_Fld21]CONVERT_IMPLICIT(numeric(16,0),[@P5],0))) ORDERED FORWARD) 0 3 2 Clustered Index Seek Clustered Index Seek OBJECT:([optimize1c].[dbo].[_AccumRgT22].[_AccumRgT22_ByDims_TRRR] AS [T2]), SEEK:([T2].[_Period]=[@P1] AND [T2].[_Fld20RRef]=[@P2] AND [T2].[_Fld19RRef]=[@P3]), WHERE:(([optimize1c].[dbo].[_AccumRgT22].[_Fld21] as [T2].[_Fld21]CONVERT_IMPLICIT(numeric(16,0),[@P4],0)) AND ([optimize1c].[dbo].[_AccumRgT22].[_Fld21] as [T2].[_Fld21]CONVERT_IMPLICIT(numeric(16,0),[@P5],0))) ORDERED FORWARD [T2].[_Fld20RRef], [T2].[_Fld21] 1 0,003125 0,0001581 32 0,0032831 [T2].[_Fld20RRef], [T2].[_Fld21] PLAN_ROW 0 1

    Вопрос почему?

    • Смирнов Евгений Алексеевич

      не отвечайте
      я увидел ответ в 6 занятии =)

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

        И хорошо бы опубликовать ответ на вопрос.
        Чтобы другие участники видели :)

        • Смирнов Евгений Алексеевич

          Все правильно, здесь и должен быть поиск по неполному условию, т.к. необходимо отсечь строки с нулевыми записями. В данном случае это не является проблемой, ведь мы практически все строки нашли по индексу, и просканировали лишь очень малую часть таблицы. Как было сказано Seek Where это далеко не всегда проблема, зависит от того объема данных который был просканирован. Источник: ©Курсы-по-1С.рф

  5. Смирнов Евгений Алексеевич

    Добрый день
    Смотрю видео с соединением нескольких таблиц
    Повторяю то что на видео
    Но у меня план запроса вот такой http://joxi.ru/82QD15LsYEPEmd
    То есть появился какой то Bitmap + значок параллелизма
    И вот вопрос
    http://joxi.ru/Q2KV371fn59bmj

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

  6. Виктор Яковлев

    Здравствуйте.

    Объясните, пожалуйста, следующие моменты:
    1) Почему используется SEEK .. WHERE, ведь имеется кластерный индекс, все условия использования соблюдены.
    2) Почему используется CONVERT_IMPLICIT и плохо ли это?

    Файл со структурой ИБ, запросом и его планом во вложении.

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

  7. Евгений

    Правильно ли я понимаю что если есть поиск по индексу идет с частичным сканирование то сканирование будет не всей таблицы а только части удовлетворяющей условию seek? Если да то зависит ли это от того кластерный индекс или обычный?
    Пример не оптимального плана с частичным сканирование:
    950 1699 |—Clustered Index Seek(OBJECT:([Test2].[dbo].[_Document556].[PK___Documen__AC8ED0C421069C50] AS [T2]), SEEK:([T2].[_IDRRef]=[Test2].[dbo].[_AccumRg22819].[_RecorderRRef] as [T1].[_RecorderRRef]), WHERE:([Test2].[dbo].[_AccumRg22819].[_RecorderTRef] as [T1].[_RecorderTRef]=CASE WHEN [Test2].[dbo].[_Document556].[_IDRRef] as [T2].[_IDRRef] IS NOT NULL THEN [@P1] ELSE NULL END) ORDERED FORWARD)

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

  8. Александр

    Здравствуйте.
    В процессе игр с разными запросами наткнулся на оператор плана Segment. Гуглевание и чтение описания понимания не прибавили. Можете пояснить, что делает этот оператор? Запрос был к срезу последних регистра сведений из вашей базы.
    Спасибо.

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

      %D0%A0%D0%B8%D1%81%D1%83%D0%BD%D0%BE%D0%BA%201.png%D0%A0%D0%B8%D1%81%D1%83%D0%BD%D0%BE%D0%BA%202.png

      • Александр

        Андрей, спасибо за подробный ответ.

  9. Евгений

    Добрый день, у меня два вопроса:
    1) Является ли проблемой если оптимизатор запроса выбрал Nested Loops при условии что верхняя таблица вернет 187 строк (ожидаемое количество) а нижняя 1 строку (ожидаемо)?
    2) Оптимизатор выбирает Nested Loops для объединения двух таблиц верхняя план 1/факт 187 нижняя план 1/факт 187.
    Обновление статистик (UPDATE STATISTICS _Reference98(и 160) WITH FULLSCAN) для обоих таблиц проблему не решило.
    План и текст запроса во вложении.

    Анализируя план сделал вывод: Учитывая что в тч документа (_Document31399_VT31435) 187 строк то и Clustered Index Seek(OBJECT:([Test2].[dbo].[_Reference160]..) выполнилось 187 раз и каждый раз вернуло по 1 строке.
    Получается что оператор выбран верный? Если вывод верный то почему именно так а не выполнилось один раз и за один развернулось 187 строк?

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

      • Евгений

        Андрей, ответьте пожалуйста и на первый вопрос.

        • Андрей Бурмистров


          (текст комментария доступен только участникам Мастер-группы)

  10. Дмитрий Ермилов

    Добрый день.
    При работе использую проведение по партиям, чтобы правильно расположить документы в пределах одной секунды и получить остатки на позицию документа, использую Границу и МоментВремени.
    На партнерском форуме прочитал что использование МоментаВремени в запросе может существенно усложнить работу запроса. Начал анализировать план запроса через Profiler, если использовать МоментВремени то присутствует оператор «Параллелизм», если заменить МоментВермени на просто Дату документа то этот оператор исчезает и запрос выполняется на порядок быстрее.
    Сервер СУБД — SQL 2014, менял уровень совместимости на 2012 и 2008, результат один и тот же.
    Платформа 8.3.5, база была в режиме совместимости, убрал совместимость, результат один и тот же.
    Подскажите, в «Параллелизме» дело или в чем другом? Спасибо.

      • Андрей Бурмистров


        (текст комментария доступен только участникам Мастер-группы)

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

      • Дмитрий Ермилов

        Почему я обратил внимание на мое проведение по партиям? До начала прослушивания курса у меня на SQL стояло «Максимальная степень параллелизма» равная 0, т.е значение по умолчанию. На основании уроков я установил значение 1 и забыл про это, но после этого начались очень медленное проведение по партиям. Решил разобраться с проблемой ну и наткнулся в итоге на проблему МоментаВремени. В итоге я переделал запрос, получаю итог на секунду до даты документа и после итог на секунду самого документа. Провел эксперимент, на исправленном запросе ставлю Макс.степень параллелизма 0 или 1 — скорость проведения не меняется. На старом запросе ставлю 1 — начинается ужасно медленное проведение, ставлю 0 сразу даже не прерывая проведение по партиям все начинает летать.

        Вопрос: получается «Максимальная степень параллелизма», установленная в 1 не всегда может быть полезно (я не отрицаю что момент времени делает плохой план запроса)?

        И еще обратил внимание, что на старом запросе, если закинуть его во временную таблицу, то даже с использованием МоментаВремени и «Максимальная степень параллелизма» = 0, то в плане запроса отсутствует оператор «Параллелизм».

        • Андрей Бурмистров


          (текст комментария доступен только участникам Мастер-группы)

  11. Ekovichev

    Если применяется HASH JOIN для таблиц, у которых ключевые поля(по которым идет соединение) и так имеют предельно низкую длину длину(1-3) символа, то вычисление хэш-функции и построение промежуточной хэш-таблицы может быть неоправданно, так ли это? Поможет ли в этом случае индексация этих полей во временных таблицах и последующее соединение этих таблиц с помощью MERGE JOIN и вообще будет ли использоваться merge join, если поля проиндексировать во временных таблицах с помощью конструкции ИНДЕКСИРОВАТЬ ПО?

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

  12. Ekovichev

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

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

  13. Sunny

    Здравствуйте Андрей, Вы говорите, что план запроса нужно читать — справа налево, но мне кажется ,что слева направо удобней и правильней, т.к. SQL выполняет план слева направо, это можно легко проверить написав запрос с использованием оператора TOP. В видео все рассказано: https://youtu.be/CXtj0lwA5Ko?t=7m25s

    • Андрей Бурмистров


      (текст комментария доступен только участникам Мастер-группы)

Комментарии закрыты