[T-SQL] Почему разыменование - это плохо?

Публикация № 805991

Разработка - Практика программирования

планы запросы файловая казалось бы

9
Обращение к полям таблицы через точку [Док.Номенклатура.Комплект] называется операцией разыменования ссылочного поля. Программисту 1С важно понимать, что даже самый маленький запрос может быть интерпретирован в 7-этажного монстра.

По мотивам //infostart.ru/public/165456/ ...

Итак, почему нижеописанный запрос стал тормозить?

            ВЫБРАТЬ
                Док.Номенклатура.Комплект КАК Комплект,      --< соединение с "Номенклатура"
                Док.Склад КАК Склад,
                Док.ПроцентБонуса КАК ПроцентБонуса,
                Док.Ссылка.Рецепт КАК Рецепт,                        --< соединение с "ЧекиККМ"
                Док.СуммаАвтоматическойСкидки КАК СуммаАвтоматическойСкидки,
                Док.ИнтернетЗаказ КАК ИнтернетЗаказ
            ИЗ
                Документ.ЧекККМ.Товары КАК Док
            ГДЕ
                Док.Ссылка.Дата МЕЖДУ &НачДата И &КонДата
                И Док.Ссылка.КассаККМ = &КассаККМ
                И Док.Ссылка.Проведен

В данном запросе есть соединение ТЧ с двумя таблицами: Документы.ЧекиККМ и Справочники.Номенклатура

Кто-то скажет, что этот запрос писал не очень грамотный программист. Но почему иногда он всё же будет работать быстро?

Вот текст SDBL и плана запроса до реструктуризации:

Fields:(
    _Reference50_rd0z0d35._Fld779,
    _Document152_VT3354_Q_000_T_001._Fld3370RRef,
    _Document152_VT3354_Q_000_T_001._Fld5855,
    _Document152_rd0z0d35._Fld5850RRef,
    _Document152_VT3354_Q_000_T_001._Fld5857,
    _Document152_VT3354_Q_000_T_001._Fld5858
)
_DOCUMENT152 (_Document152_rd0z0d35) RANGE SCAN USING INDEX (_DOCUMEN152_BYFIELD3376_RTR) (2 fields)
WHERE
        (_Document152_rd0z0d35._Date_Time >= 20180326000000)
        AND
        (_Document152_rd0z0d35._Date_Time <= 20180326235959)
        AND
        (_Document152_rd0z0d35._Posted = TRUE)
NESTED LOOP
_DOCUMENT152_VT3354 (_Document152_VT3354_Q_000_T_001) RANGE SCAN USING INDEX (_DOCUMEN152_VT3354_INTKEYIND) (1 fields)
WHERE
        (_Document152_VT3354_Q_000_T_001._Document152_IDRRef = _Document152_rd0z0d35._IDRRef)
NESTED OUTER LOOP
_REFERENCE50 (_Reference50_rd0z0d35) RANGE SCAN USING INDEX (_IDRREFIDX) (1 fields)
WHERE
        (_Document152_VT3354_Q_000_T_001._Fld3356RRef = _Reference50_rd0z0d35._IDRRef)

Statistics: RecordsScanned = 0, ParseTime = 0, ExecuteTime = 0, BuffersMemory = 8192, ResultRecords = 0, RecordSize = 51

Выполняется за 16мс.

Тот же запрос, но после смены режима совместимости, добавления пары полей и рестуктуризации:

Fields:(
    T2._Fld779,
    T1._Fld3370RRef,
    T1._Fld5855,
    T3._Fld5850RRef,
    T1._Fld5857,
    T1._Fld5858
)
_DOCUMENT152_VT3354 (T1) FULL SCAN

NESTED OUTER LOOP
_REFERENCE50 (T2) RANGE SCAN USING INDEX (_IDRREFIDX) (1 fields)
WHERE
        (T1._Fld3356RRef = T2._IDRRef)
NESTED LOOP
_DOCUMENT152 (T3) RANGE SCAN USING INDEX (_IDRREFIDX) (1 fields)
WHERE
        (T3._Date_Time >= 20180326000000)
        AND
        (T3._Date_Time <= 20180326235959)
        AND
        (T3._Fld3341RRef = ABC7C89CDC2D6B5E11E14357A2462119)
        AND
        (T3._Posted = TRUE)
        AND
        (T1._Document152_IDRRef = T3._IDRRef)

Statistics: RecordsScanned = 530187, ParseTime = 1, ExecuteTime = 2979, BuffersMemory = 8192, ResultRecords = 0, RecordSize = 51

Выполняется дольше 5 секунд, количество считанных записей - полмиллиона! Запрос тормозит, т.к. sdbl (кстати, вообще кто-нибудь знает как он расшифровывается??) выбирает неоптимальный план.

Что заставило планировщик изменить порядок выборки с Товары<-ЧекККМ<-Номенклатура на Товары<-Номенклатура<-ЧекККМ ?

Наблюдение: После обновления конфигурации таблица товаров чека уехала с середины файловой базы в конец. 
https://yadi.sk/i/LeXVBJhJ3ToM6q

В данном случае одинаковый запрос выполняется по-разному.



В каком порядке правильно писать соединения?

Рассмотрим ещё одну задачу:

Задача 2.

 

Необходимо получить весь список номенклатуры из всех документов «Отчет о розничных продажах» за указанный период. Существующий запрос выполняется слишком медленно:

ВЫБРАТЬ

            ОтчетОРозничныхПродажахТовары.Номенклатура

ИЗ

            Документ.ОтчетОРозничныхПродажах.Товары КАК ОтчетОРозничныхПродажахТовары

ГДЕ

ОтчетОРозничныхПродажахТовары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода

СГРУППИРОВАТЬ ПО

            ОтчетОРозничныхПродажахТовары.Номенклатура

 

Предложить вариант оптимизации запроса.

Бытует мнение, что здесь сначала выберутся все документы, затем все товары из них, только потом наложится условие по дате на всё полное соединение и движку придется перебрать все товары всех документов. НО это не так!

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

2. Запрос:

ВЫБРАТЬ РАЗЛИЧНЫЕ

        ОтчетОРозничныхПродажахТовары.Номенклатура

ИЗ

        Документ.ОтчетОРозничныхПродажах.Товары КАК ОтчетОРозничныхПродажахТовары

                       ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ОтчетОРозничныхПродажах КАК ШапкаДокумента

                       ПО ОтчетОРозничныхПродажахТовары.Ссылка = ШапкаДокумента.Ссылка

                       И ШапкаДокумента.Дата МЕЖДУ &НачалоПериода И &КонецПериода

Когда я встретился с этой задачей, я не знал как смотреть план запроса в файловой базе (ИР->КонсольЗапросов->ЗапросРезультата->Трасса) и не мог понять какое соединение правильней применять. Даже сейчас, замерив скорость выполнения я получаю одинаковые цифры.

Вот план исходной задачи:

Fields:(
    T1._Fld2047RRef
)
_DOCUMENT117 (T2) RANGE SCAN USING INDEX (_DOCUMEN117_BYDOCDATE_TR) (1 fields)

NESTED LOOP
_DOCUMENT117_VT2039 (T1) RANGE SCAN USING INDEX (_DOCUMEN117_VT2039_INTKEYIND) (1 fields)
WHERE
        (T1._Document117_IDRRef = T2._IDRRef)

GROUPING
Statistics: RecordsScanned = 20825, ParseTime = 0, ExecuteTime = 28, BuffersMemory = 228412, ResultRecords = 9747, RecordSize = 18

Вот план предлагаемого решения:

Fields:(
    T1._Fld2047RRef
)
_DOCUMENT117 (T2) RANGE SCAN USING INDEX (_DOCUMEN117_BYDOCDATE_TR) (1 fields)

NESTED LOOP
_DOCUMENT117_VT2039 (T1) RANGE SCAN USING INDEX (_DOCUMEN117_VT2039_INTKEYIND) (1 fields)
WHERE
        (T1._Document117_IDRRef = T2._IDRRef)

WITHOUT DUPLICATES
Statistics: RecordsScanned = 20825, ParseTime = 0, ExecuteTime = 39, BuffersMemory = 228412, ResultRecords = 9747, RecordSize = 18

Планы одинаковы! В данном случае способ соединения неважен. Если мы делаем левое соединение и накладываем условие на правую таблицу, то оно отрабатывает как внутреннее соединение согласно данному условию.

Здесь же разные запросы выполняются одинаково.


 

Вывод: не важно как написан запрос - важно как он выполнится. Но это особая, черная магия...

ps: казалось бы, причем тут разыменование?

9

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. DimDiemon 78 28.03.18 15:17 Сейчас в теме
Каков смысл написания этой статьи?
Ни один вопрос не раскрыт...
wowik; cefew; klinval; sergelemon; kalyaka; zarucheisky; +6 Ответить
2. ipoloskov 65 28.03.18 15:49 Сейчас в теме
Вывод: не важно как написан запрос - важно как он выполнится. Но это особая, черная магия...

В этом и смысл правильного написания запросов - чтобы он Всегда выполнялся оптимально. Вне зависимости от фазы луны и настроения сервера. И никакой магии. В первом примере отца русской демократии спасет, наверное, это:
        ВЫБРАТЬ
                Док.Номенклатура.Комплект КАК Комплект,      --< соединение с "Номенклатура"
                Док.Склад КАК Склад,
                Док.ПроцентБонуса КАК ПроцентБонуса,
                ЧекККМ.Рецепт КАК Рецепт,
                Док.СуммаАвтоматическойСкидки КАК СуммаАвтоматическойСкидки,
                Док.ИнтернетЗаказ КАК ИнтернетЗаказ
            ИЗ Документ.ЧекККМ КАК ЧекККМ 
                ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ЧекККМ.Товары КАК Док
                     ПО ЧекККМ.Ссылка = Док.Ссылка
            ГДЕ
                ЧекККМ.Дата МЕЖДУ &НачДата И &КонДата
                И ЧекККМ.КассаККМ = &КассаККМ
                И ЧекККМ.Проведен
Показать
mitia.mackarevich; Михаська; zarucheisky; +3 Ответить
3. МихаилМ 28.03.18 22:10 Сейчас в теме
(2) на данном этапе развития субд запрос ВСЕГДА не может выполняться оптимально.

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

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

опять же любимая фирма 1с не забывает радовать неудачными решениями в платформе.

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

и все увеличивающиеся вычислительные мощности не всегда.
Поэтому задачи проектирования и эксплуатации ис - два различных ремесла
8. bulpi 158 29.03.18 11:12 Сейчас в теме
По запросу 1.
"Кто-то скажет, что этот запрос писал не очень грамотный программист. "

Возможно, это я не очень грамотный программист. Но я не вижу в этом запросе ничего крамольного. И вариант , предложенный в (2) не будет быстрее (ИМХО).


По запросу 2.
Капитан Очевидность с нами! Тут даже обсуждать нечего.
4. nytlenc 29.03.18 10:35 Сейчас в теме
Коля ))) Привет тебе от Саши С. Очень жаль что ты так и не понял сути этой задачи даже со временем....
В общем опять двойка. Сейчас объясню почему.
СУБД сама определяет, как построить план запроса, в том или ином случае, и это тоже кстати особая магия. Таким образом, чтобы обеспечить оптимальное выполнение запроса, нужно всегда стараться изначально писать оптимальный запрос и придерживаться всех рекомендаций по его оптимизации. Подробнее тут: https://its.1c.ru/db/v8std#browse:13:-1:66:95 (ИТС Подписку пробную оформишь сам, и это больше совет, который к конкретному вопросу не имеет дела).

Рассмотрим снова задачу 2.
Необходимо получить весь список номенклатуры из всех документов «Отчет о розничных продажах» за указанный период. Существующий запрос выполняется слишком медленно:

ВЫБРАТЬ
            ОтчетОРозничныхПродажахТовары.Номенклатура
ИЗ
            Документ.ОтчетОРозничныхПродажах.Товары КАК ОтчетОРозничныхПродажахТовары
ГДЕ
ОтчетОРозничныхПродажахТовары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
            ОтчетОРозничныхПродажахТовары.Номенклатура
Показать

ты пишешь, что
Бытует мнение, что здесь сначала выберутся все документы, затем все товары из них, только потом наложится условие по дате на всё полное соединение и движку придется перебрать все товары всех документов. НО это не так!


Действительно это не так :) На самом деле берётся вся номенклатура из всех табличных частей документов. Накладывается условие по дате и т.д..
Но суть не в этой игре слов, и даже не в условии по дате или каком-либо другом условии запроса… А буквально в следующем!
Посмотри внимательно на свои планы запросов и теперь хорошо подумай над следующий фразой:

В чем разница между операторами DISTINCT и GROUP BY?
DISTINCT - указывает, что для вычислений используются только уникальные значения столбца. NULL считается как отдельное значение. Если нужно удалить только дубликаты лучше использовать DISTINCT. GROUP BY группирует выбранный набор строк для получения набора сводных строк по значениям одного или нескольких столбцов, или выражений. GROUP BY создает отдельную группу для всех возможных значений (включая значение NULL). GROUP BY лучше использовать для определения групп выходных строк, к которым могут применяться агрегатные функции (COUNT, MIN, MAX, AVG и SUM).


Теперь снова посмотри на свои планы запросов и снова подумай.
Представь базу данных в которой есть всего 2 элемента справочника, ложка и вилка.
У тебя есть 5 миллионов документов, в которых есть в каждом ровно по две строки ложка и вилка и все они попадают под условие выборки. Итого ты получаешь 10 миллионов строк.
В случае если используется GROUP BY (СГРУППИРОВАТЬ ПО), все строки (все 10 миллионов) будут собираться в одну большую группу и уже после этого с ними будут проводиться какие-то дальнейшие действия, в данном случае ты получишь ссылку на элементы справочника – всего два элемента…
При использовании DISTINCT в свою очередь СУБД откинет все повторяющиеся строки и оставит только уникальные. В нашем случае при 10 миллионах будет отброшено 9 999 998 строк и возвращено всего 2, ложка и вилка, т.к. остальные строки неуникальные и повторяются.
Теперь заключительный вопрос, что отработает быстрее и займет меньше ресурсов СУБД в указанном выше случае с 10 миллионами строк. Даже при условии что у тебя сразу наложилось условие по дате и и в это условие выборки как раз таки эти 10 миллионов строк попали?
ВЫБРАТЬ
            ОтчетОРозничныхПродажахТовары.Номенклатура
ИЗ
            Документ.ОтчетОРозничныхПродажах.Товары КАК ОтчетОРозничныхПродажахТовары
ГДЕ
ОтчетОРозничныхПродажахТовары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
            ОтчетОРозничныхПродажахТовары.Номенклатура
Показать

Или
ВЫБРАТЬ РАЗЛИЧНЫЕ
            ОтчетОРозничныхПродажахТовары.Номенклатура
ИЗ
            Документ.ОтчетОРозничныхПродажах.Товары КАК ОтчетОРозничныхПродажахТовары
ГДЕ
ОтчетОРозничныхПродажахТовары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
 

?
5. nytlenc 29.03.18 10:49 Сейчас в теме
В заключение к вышесказанному хочется добавить в части разыменования ссылочных полей - ты забыл упомянуть например RLS в случае использования которого на такой запрос нагромоздится еще куча различных соединений и он начнет тормозить еще больше. Так же следует помнить про составные типы в основном из-за которых и даются подобные рекомендации по оптимизации. Например использовать конструкцию ВЫРАЗИТЬ()
6. herfis 285 29.03.18 11:01 Сейчас в теме
Увидел только одно соображение, почему "разименование это плохо" для простых случаев (без составных типов и прочих понятных вариаций) - мол на файловом движке может быть выбран неоптимальный план выполнения. А может и не будет. А может починят во очередном релизе.
И что, ради этого отказываться от средства, специально призванного упрощать описание простых деклараций?
Не вижу смысла. Проще писать как проще и разруливать узкие места при их появлении. А не заниматься преждевременной оптимизацией.
alex5550; корум; awk; kuzyara; Vovan1975; dmt; +6 Ответить
7. nytlenc 29.03.18 11:07 Сейчас в теме
(6)
Не вижу смысла. Проще писать как проще и разруливать узкие места при их появлении. А не заниматься преждевременной оптимизацией.

А может проще не говонокодить создавать эти узкие места изначально оформляя оптимальный код?
А вы подумали над тем, что все время оставляя после себя не оптимальный говнокод как минимум ставите грабли другим коллегам, которые будут ковыряться в вашем говнокоде и как максимум каждый раз оставляете узкие места в системе. Сразу виден девиз
9. herfis 285 29.03.18 11:13 Сейчас в теме
(7) Т.е. любое использование разыменование в запросах 1С вы автоматически определяете в "говнокод"? А какое же тогда название вы приберегли для разработчиков платформы, давшим в руки разработчикам лишний и вредный (по-вашему) инструмент?
Лично я не сталкивался в продакшене (клиент-сервере) с ситуациями, где использование неявных соединений в простых случаях прямо вело к появлению узких мест. Использование разименования в простых случаях - наоборот, повышает читабельность кода.
10. TODD22 18 29.03.18 11:16 Сейчас в теме
Да вроде как разыменование будет преобразовано в левое соединение. И что его руками написать, что разыменованием сделать по идее в простых случаях должно дать один и тот же результат. Или нет?
15. nytlenc 29.03.18 15:25 Сейчас в теме
(9) Блин да причем тут разыменование полей?
Цитирую Вас дословно

Проще писать как проще и разруливать узкие места при их появлении.


Это и называется говнокодить.
18. herfis 285 29.03.18 15:33 Сейчас в теме
(15)
Блин да причем тут разыменование полей?

Как это причем? Мы что, о мухах общались? Вы выдернули фразу из контекста, экстраполировали ее как вам захотелось и на основании этих эротических фантазий обвиняете меня в говнокодерстве. Перечитайте мой коммент, последнюю фразу из которого вы выдернули.
11. herfis 285 29.03.18 11:36 Сейчас в теме
(7) Для тех, кто пишет статьи на ИТС, вы возможно также найдете пару теплых слов. Цитата:
"В 1С:Предприятии 8 допускается обращение к свойствам объектов через одну или несколько точек, например, «Номенклатура.Поставщик.Страна». Это позволяет значительно упростить написание запросов. Рекомендуется всегда пользоваться разыменованием полей там, где это возможно, чтобы не усложнять запросы лишними конструкциями."
rincewind; user828972; sergathome; serpent; +4 Ответить
13. sergathome 29.03.18 14:35 Сейчас в теме
(11) Столкнулся тут. В бух 3. Производился поиск объекта по его допсвойству. Запрос выглядел примерно так:
ВЫБРАТЬ
	               	ДополнительныеСведения.Объект.Ссылка КАК ОбъектСсылка
	               ИЗ
	               	РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
	               ГДЕ
	               	ДополнительныеСведения.Свойство = &Свойство
	               	И ДополнительныеСведения.Значение = &Значение

В половине случаев исполняется нормально - сначала отбирает записи регистра, потом соединяет с объектами, в половине - угадай как ;))
Не смешно, на самом деле...
14. herfis 285 29.03.18 15:09 Сейчас в теме
(13) Это фигня какая-то, а не запрос.
1) ты разыменовываешь поле составного типа, а это совершенно особый случай. Спор шел о простых случаях.
2) непонятно, зачем ты это делаешь - ведь "Объект" это уже ссылка. А ты на ровном месте провоцируешь соединение со всеми таблицами составного типа.
3) Что значит, угадай как? Сиквел-запрос адекватный, но выбирается неоптимальный план выполнения? Тогда причем здесь разыменование?
16. sergathome 29.03.18 15:26 Сейчас в теме
(14) Просто пример, как простая швейная машинка Зингера легко превращается в аццкую. Ошибся в запросе - по памяти писал, там, на самом деле, отбор по ПометкаУдаления был, а не ссылка, конечно, выбиралась. Но самое смешное, что даже вот в таком виде:
ВЫБРАТЬ
		               	ДополнительныеСведения.Объект КАК ОбъектСсылка
		               ПОМЕСТИТЬ Тбл
		               ИЗ
		               	РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
		               ГДЕ
		               	ДополнительныеСведения.Свойство = &Свойство
		               	И ДополнительныеСведения.Значение = &Значение
		               ;
		               
		               ////////////////////////////////////////////////////////////­////////////////////
		               ВЫБРАТЬ
		               	Тбл.ОбъектСсылка КАК ОбъектСсылка
		               ИЗ
		               	Тбл КАК Тбл
		               ГДЕ
		               	НЕ Тбл.ОбъектСсылка.ПометкаУдаления = ИСТИНА
Показать

оно исполняется через раз - оптимизатор упорно пытается, таки, во втором подзапросе, сначала выбирать все объекты и потом только проверять.
Я всё это к тому, что рекомендациями 1С весьма часто можно смело подтираться.
19. ipoloskov 65 29.03.18 15:40 Сейчас в теме
(16)
оптимизатор упорно пытается, таки, во втором подзапросе, сначала выбирать все объекты и потом только проверять

А как еще он должен делать?
20. sergathome 29.03.18 15:47 Сейчас в теме
(19) Как учит нас партия и правительство производитель платформы, при использовании временной таблицы оптимизатор (якобы) рассчитывает её статистику и по итогам делает выводы. В представленном мною варианте количество записей в Тбл несопоставимо вообще с количеством записей по объектам и тем не менее...
21. ipoloskov 65 29.03.18 15:50 Сейчас в теме
(20) а, кажется понял - оптимизатор выбрал все объекты из базы с ОбъектСсылка.ПометкаУдаления = ЛОЖЬ, и потом соединил их с Тбл?
sergathome; +1 Ответить
22. sergathome 29.03.18 15:52 Сейчас в теме
(21) +1
Но даже не это самое несмешное. Самое - это то, что в половине случаев он делает правильно...
23. ipoloskov 65 29.03.18 16:02 Сейчас в теме
(22) значит, оптимизатор думает, что объектов меньше, чем записей в Тбл. Думаю, это связано с составным типом. Возможно, оптимизатор лезет в первую таблицу составного типа, видит, что там нет записей или их мало, и на этом успокаивается.
25. sergathome 29.03.18 16:08 Сейчас в теме
(23) так оно и есть. в данном случае причина скорее всего в этом. Если бы платформщики позаботились о том, как задать для смешанного типа тип по-умолчанию... Но об этом можно только мечтать. (с) Зато рекомендаций дурацких на ИТСе - масса :(
26. herfis 285 29.03.18 16:13 Сейчас в теме
(25)
Зато рекомендаций дурацких на ИТСе - масса :(

По особенностям разыменования составных полей на ИТС есть специальная статья. Так что не надо ля-ля.
27. sergathome 29.03.18 16:23 Сейчас в теме
Статья - это прекрасно. В одной пишем одно, в другой - другое... Документации внятной нет, как и не было.
12. kuzyara 815 29.03.18 11:38 Сейчас в теме
(7) Вот любишь потеоризировать о правильности и оптимальность запроса!
Нет взять в руки профайлер да проверить исполнение:
Fields:(
T1._Fld3356RRef
)
_DOCUMENT152 (T2) RANGE SCAN USING INDEX (_DOCUMEN152_BYDOCDATE_TR) (1 fields)

NESTED LOOP
_DOCUMENT152_VT3354 (T1) RANGE SCAN USING INDEX (_DOCUMEN152_VT3354_INTKEYIND) (1 fields)
WHERE
(T1._Document152_IDRRef = T2._IDRRef)

GROUPING
Statistics: RecordsScanned = 262972, ParseTime = 0, ExecuteTime = 849, BuffersMemory = 188372, ResultRecords = 7529, RecordSize = 18

Fields:(
T1._Fld3356RRef
)
_DOCUMENT152 (T2) RANGE SCAN USING INDEX (_DOCUMEN152_BYDOCDATE_TR) (1 fields)

NESTED LOOP
_DOCUMENT152_VT3354 (T1) RANGE SCAN USING INDEX (_DOCUMEN152_VT3354_INTKEYIND) (1 fields)
WHERE
(T1._Document152_IDRRef = T2._IDRRef)

WITHOUT DUPLICATES
Statistics: RecordsScanned = 262972, ParseTime = 0, ExecuteTime = 928, BuffersMemory = 188372, ResultRecords = 7529, RecordSize = 18

https://yadi.sk/i/jvgtfkx03TsMCV
Одинаковы они! Яж говорю, это ОСОБАЯ магия!
17. nytlenc 29.03.18 15:28 Сейчас в теме
Коля )))) Ты так и не понял )))
Возьми базу с 10 миллионами строк и выполни )))) Потом покажешь результаты и замеры.
28. kuzyara 815 29.03.18 19:16 Сейчас в теме
(17) У меня запросы из (4) выполняются одинаково.
Если не трудно, покажи свой вывод субд.
29. kuzyara 815 30.03.18 03:53 Сейчас в теме
(17)
Теперь заключительный вопрос, что отработает быстрее

Монопенисуально, блджад! http://www.itprotoday.com/microsoft-sql-server/distinct-vs-group
Q: Should I use DISTINCT or GROUP BY to eliminate duplicates in a result set?

A: A DISTINCT and GROUP BY usually generate the same query plan, so performance should be the same across both query constructs. For example, say you want to generate a unique list of product IDs from the Order Details table in Northwind. The two following queries both give you a correct answer:

SEL ECT DISTINCT od.productid
FROM \[order details\] OD
SEL ECT od.productid
FR OM \[order details\] OD
GROUP BY od.productid
Which one is more efficient? Checking execution plans is a simple way to determine the relative efficiency of different queries that generate the same result set. Enable Show Execution Plan in Query Analyzer by pressing Ctrl+K or by selecting Show Execution Plan fr om the Query menu. Then, execute the above queries. Figure 1 shows that the execution plans of both queries are the same. In most cases, DISTINCT and GROUP BY generate the same plans, and their performance is usually identical.

So, how do you decide which SQL command to use? GROUP BY is required if you're aggregating data, but in many cases, DISTINCT is simpler to write and read if you aren't aggregating data. Pick whichever syntax you prefer for your situation.

Саша, всё, не буду больше спорить про производительность, в данном случае она одинакова.
Но синтаксически DISTINCT здесь, естественно, правильнейлогичней.
32. nytlenc 30.03.18 10:12 Сейчас в теме
(29)

Саша, всё, не буду больше спорить про производительность, в данном случае она одинакова.
Но синтаксически DISTINCT здесь, естественно, правильнейлогичней.


ну наконец то... )))
33. kuzyara 815 30.03.18 10:55 Сейчас в теме
(32) Наверное, я слишком буквально понял задачу оптимизации... А ответ на поверхности! )))
24. herfis 285 29.03.18 16:08 Сейчас в теме
Опять в сторону ушли. Публикация-то ведь о том, что даже в случае несоставных полей разыменование это плохо.
Во всяком случае, я ее понял именно так. Или я вообще не понял, о чем публикация.
30. KAV2 30.03.18 06:14 Сейчас в теме
Все таки оптимизацию первого запроса полагаю делать надо в случае возникновения проблем с производительностью, когда запрос реально тормозит. Заранее устранять разименовывание в этом конкретном запросе я бы не стал, не целесообразно, потому что как правило все же запрос будет выполняться оптимально, да и по хорошему надо денормализировать - записывать данные в регистр, если же регистра нет, то это либо ошибка проектирования либо просто задача не особо важная и 5 сек. вполне можно подождать.
31. spezc 595 30.03.18 06:24 Сейчас в теме
посмотрите на типовые. "разыменование" там чуть меньше чем везде.
ipoloskov; +1 Ответить
34. awk 692 30.03.18 17:56 Сейчас в теме
1. Оптимизировать можно только работающее решение - оптимизация неработающего решения бесполезна.
2. Писать надо как можно проще - на сложный код требуется больше времени из-за большей вероятности ошибки.
3. Оптимизировать надо когда это требуется, а не "пожизни". Нет смысла оптимизировать код который работает 0.1 секунды. Если вы его оптимизируете и он будет работать 0.001 секунду, то разницу 0.099 секунды не заметит НИКТО. И ваше стократное улучшение в и затраченное время пойдет "псу под хвост".
alex5550; Synoecium; kostas; Inkasor; +4 Ответить
35. AlexeyDmuhin 04.04.18 09:12 Сейчас в теме
(34) В ларьке может и не заметно, а вот на сервере, где несколько сотен пользователей, очень даже заметно. Ресурс не резиновый ни разу
36. awk 692 04.04.18 11:18 Сейчас в теме
(35) "А за козла придется ответить перед всем стадом" :)

Тест кейс:

Дано: ларек 700 человек. заполнение документа по ЗП 24 минуты.
Действие: Сажусь на неделю, результат заполнение документа меньше минуты (индексация, вынос запросов за циклы, ограничение аппетитов запросов условиями)
Результат: Кадровик перестал успевать попить чаю.
Вывод: Я, дебил, не посмотрел частоту формирования документа.

Ты то же ресурс, и то же не резиновый. Ограничение рабочего дня, для умных - 8 часов, для дебилов (я себя из них не выделяю) 24 часа в сутках - физическое ограничение.
37. AlexeyDmuhin 04.04.18 11:52 Сейчас в теме
(36) отличный результат! После сотого заполнения вы отобьете временные затраты :), по стоимости часов сами считайте :)
38. awk 692 04.04.18 12:20 Сейчас в теме
(37)

1. 24 * 100 / 60 = 40 часов
2. 5 * 8 = 40 часов

Вот только у меня ЗП раза в три выше чем у оператора.следовательно:


24 * Х / 60 = 120
Х = 120 *60 / 24 = 300 раз. 300 месяцев = 25 лет.

Дебил в тест-кейсе я. Даже если он по 10 раз запустит в месяц это все равно 2.5 года. А зарплатные документы запускают раза 2-3. 1С новые конфигурации раз в 3-5 лет выпускает. Вот оно и "псу под хвост"
alex5550; +1 Ответить
40. AlexeyDmuhin 04.04.18 14:41 Сейчас в теме
(38) Дело в том, что гораздо чаще все сводится не только к одному себе любимому, высокооплачиваемому спецу. Не забывайте, что в системе с Вашим запросом могут работать большое количество людей и все эти секунды, минуты и т.д. выливаются в увеличенное время ожидания. И запросов таких может быть много и все вместе это будет давать колоссальную нагрузку из-за не оптимальных выборок данных. Попробуй потом разобраться - действительно нужен новый сервер или руки программиста все могут исправить. Пример с заполнением документа ЗП действительно не показатель.
39. herfis 285 04.04.18 12:25 Сейчас в теме
(36) Речь не про оптимизацию эксплуатируемой системы, а про первоначальное написание качественного кода (простого, читабельного, но при этом обеспечивающего хорошую масштабируемость). Здесь невозможно говорить "в общем", можно обсуждать только конкретные ситуации.
Тут все сильно зависит от требований к системе, опыта и интуиции разработчика, сложности написания более масштабируемого кода и его читабельности.
Но вот усложнение запросов за счет исключения разыменований я однозначно отношу к преждевременным оптимизациям. Потому как разработку и сопровождение оно усложняет, а "выстрелить" может только при специфическом "затыке". При этом реальный смысл этот "выстрел" получит только при попадании в узкое место.
alex5550; awk; +2 Ответить
41. awk 692 04.04.18 23:02 Сейчас в теме
(39) https://checkist.livejournal.com/160130.html

Вот приемочное тестирование и должно содержать нагрузочные тесты, как и второй этап требования по быстродействию. До кода можно вообще не добраться, если взять готовый продукт.
alex5550; +1 Ответить
Оставьте свое сообщение

См. также

Полезные процедуры и функции для программиста 142

Статья Программист Нет файла v8 1cv8.cf Россия Бесплатно (free) Практика программирования Универсальные функции

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

07.10.2019    9358    HostHost    23       

Агрегатные функции СКД, о которых мало кто знает 343

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Пользуетесь ли Вы всеми возможными агрегатными функциями, которые предоставляет система компоновки данных? Если Вы используете только: СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, то эта статья для Вас.

05.09.2019    13522    ids79    44       

Три костыля. Сказ про фокусы в коде 123

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Разработка

Три интересных (или странных) костыля в коде, которые могут помочь в повседневных и не очень задачах.

03.09.2019    9424    YPermitin    68       

Отслеживание выполнения фонового задания 141

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Универсальные функции Разработка

Запуск фонового задания из модуля внешней обработки. Отслеживание выполнения задания в виде прогресса, расположенного на форме.

17.08.2019    10864    ids79    16       

Функции СКД: ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив 254

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Подробное описание и использование внутренних функций системы компоновки данных: Вычислить, ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив, ВычислитьВыражениеСГруппировкойТаблицаЗначений.

08.08.2019    14762    ids79    30       

Фоновое выполнение кода в 1С - это просто 120

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

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

02.08.2019    11623    avalakh    21       

СКД - наборы данных и связи между ними, создание собственной иерархии, вложенные отчеты 131

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Набор данных объект. Использование в схеме компоновки нескольких наборов данных. Различные варианты связи наборов: объединение, соединение. Использование иерархии в отчетах на СКД. Создание собственной иерархии, иерархия детальных записей. Использование вложенных схем в отчетах на СКД.

26.07.2019    13359    ids79    6       

СКД - использование расширений языка запросов, секция ХАРАКТЕРИСТИКИ 151

Статья Программист Нет файла v8 v8::СКД Бесплатно (free) Инструментарий разработчика Практика программирования

Автоматическое и не автоматическое заполнение полей компоновки данных. Использование расширений языка запросов для СКД «{…}», секция ВЫБРАТЬ, секция ГДЕ, параметры виртуальных таблиц. Автоматизированное использование дополнительных данных в запросе: секция ХАРАКТЕРИСТИКИ.

17.07.2019    11705    ids79    27       

Регистры сведений. За кулисами 129

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

Небольшие заметки по внутреннему устройству регистров сведений.

09.07.2019    9146    YPermitin    12       

"Меньше копипаста!", или как Вася универсальную процедуру писал 183

Статья Программист Стажер Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования Разработка

Программист Вася разбирает подход создания универсальных методов на примере программного вывода СКД.

04.07.2019    8225    SeiOkami    49       

Создание отчетов с помощью СКД - основные понятия и элементы 209

Статья Программист Нет файла v8 v8::СКД Бесплатно (free) Практика программирования Математика и алгоритмы

Основные принципы работы СКД. Понятия схемы компоновки и макета компоновки. Описание основных элементов схемы компоновки: наборы данных, поля, вычисляемые поля, ресурсы, параметры.

25.06.2019    21504    ids79    17       

Многопоточное ускорение однопользовательских нагрузок в 1С + Microsoft SQL Server 2017 179

Статья Программист Нет файла v8 v8::Запросы Бесплатно (free) Практика программирования Разработка

Взаимодействие с Microsoft SQL Server нередко вызывает трудности у 1С-ников, а потому интересны любые моменты, связанные с его использованием. О своем опыте работы с новым SQL Server 2017 участникам конференции Infostart-2018 рассказал директор ООО «Аналитика софт» Дмитрий Дудин.

11.06.2019    12879    dmurk    134       

Регистры накопления. Структура хранения в базе данных 176

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

Структура хранения регистров накопления в базе данных для платформы 1С:Предприятие 8.x. Первая часть в серии публикаций.

16.05.2019    19431    YPermitin    27       

Выполнение внешней обработки в фоновом задании 149

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

Подробное описание подхода к созданию длительной операции на основе внешней обработки. Реализация протестирована на 1С 8.3.12.1714 (x64).

11.05.2019    11550    Eret1k    23       

Выгрузка документа по условию 5

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Разработка

Что делать, если документы нужно выгружать не все подряд, а по какому-то фильтру: статусу, дате, набору условий... А что если он соответствовал этим условиям, а потом перестал? А если потом опять начал? Такие ситуации заставили попотеть не одного программиста.

25.04.2019    6340    m-rv    2       

Как прикрутить ГУИД к регистру сведений 23

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Перенос данных из 1C8 в 1C8 Разработка

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

16.04.2019    8991    m-rv    16       

О расширениях замолвите слово... 194

Статья Программист Стажер Нет файла v8 Бесплатно (free) Практика программирования Разработка

О чём стоит задуматься при принятии решения о создании расширения конфигурации…

07.04.2019    18004    ellavs    125       

Git-репозитории для 1С-кода (опыт использования при небольших проектах) 202

Статья Программист Стажер Нет файла v8 Windows Бесплатно (free) Практика программирования Разработка

Инструкции по взаимодействию с Git-репозиторием, которые писались для тех наших программистов, которые вообще никогда не работали с Git (руководства в духе "Как получить код из git-репозитория?", "Как отправить код в git-репозиторий")...

28.03.2019    14165    ellavs    83       

Трюки с внешними источниками данных 166

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

Некоторые трюки для преодоления ограничений внешних источников данных.

14.03.2019    14582    YPermitin    52       

Возможности типовых шаблонов ограничения доступа на уровне записей (RLS) 166

Статья Программист Нет файла v8 v8::Права Бесплатно (free) Практика программирования БСП (Библиотека стандартных подсистем) Роли и права

Краткий обзор применения типовых шаблонов ограничения доступа на уровне записей в конфигурациях, созданных на базе БСП: #ПоЗначениям, #ПоНаборамЗначений, #ПоЗначениямРасширенный, #ПоЗначениямИНаборамРасширенный

03.02.2019    17655    ids79    9       

EnterpriseData – часть 2. Процесс выгрузки данных 127

Статья Программист Нет файла v8 v8::УФ Россия Бесплатно (free) Практика программирования Обмен через XML

Основные этапы выгрузки данных через ED, обработчики событий выгрузки, правила обработки данных, правила конвертации объектов, конвертация свойств первого и второго этапов, процедуры БСП, используемые при выгрузке данных, структура «КомпонентыОбмена».

26.12.2018    14040    ids79    27       

Новый подход к обмену данными EnterpriseData 207

Статья Программист Нет файла v8 v8::УФ Россия Бесплатно (free) Практика программирования Обмен через XML

Хочу предложить Вашему вниманию цикл статей, посвященных обмену данными через универсальный формат (EnterpriseData или ED).

14.12.2018    23468    ids79    72       

EnterpriseData - пример доработки правил конвертации без использования КД 3.0 в расширении конфигурации 119

Статья Программист Нет файла v8 v8::УФ БП3.0 УТ11 Россия Windows Бесплатно (free) Практика программирования Обмен через XML

В статье подробно описан реальный пример доработки обмена данными через EnterpriseData (универсальный формат обмена) между конфигурациями УТ 11.4 и Бухгалтерия 3.0

16.11.2018    20620    ids79    20       

Программное заполнение пользовательских параметров и отборов СКД 136

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

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

13.11.2018    22504    Unk92    19       

Автоматические и управляемые блокировки применительно к типовым конфигурациям 1С 127

Статья Программист Нет файла v8 v8::blocking 1cv8.cf Бесплатно (free) Математика и алгоритмы Практика программирования

Основные принципы работы с режимами автоматических и управляемых блокировок в 1С Предприятие 8. Теория и применение в типовых конфигурациях: БП, УТ, ЕРП

10.11.2018    22490    ids79    40       

Вспомогательные инструкции в коде 1С 106

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

Помогаем редактору кода 1С помогать нам писать и анализировать код.

15.10.2018    21665    tormozit    100       

Произвольный код в фоновом режиме 165

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

Задача: реализовать выполнение произвольного кода в фоновом режиме без изменения конфигурации, т.е. во внешней обработке.

03.09.2018    15925    nikita0832    42       

Основные понятия и механизмы оптимизации клиент-серверного взаимодействия в 1C 147

Статья Программист Нет файла v8 Россия Бесплатно (free) Математика и алгоритмы Практика программирования

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

23.08.2018    23167    Rain88    42       

Повышаем эффективность разработки правил обмена 125

Статья Программист Нет файла v8 КД ОС Бесплатно (free) Практика программирования Перенос данных из 1C8 в 1C8

Как повысить скорость и качество разработки правил обмена? Как вести групповую разработку правил обмена? Как облегчить сопровождение правил обмена после передачи в эксплуатацию? Об этом и многом другом вы можете узнать из этой статьи.

25.06.2018    20435    olegtymko    47       

Введение в механизм представлений в ЗУП ред. 3 156

Статья Программист Нет файла v8 v8::СПР ЗУП3.x Бесплатно (free) Практика программирования

В нашей организации на первом же телефонном собеседовании на должность разработчика по ЗУП ред. 3 вас обязательно спросят о том, что такое "Представления".

04.06.2018    25823    xrrg    82       

Как сделать запрос на изменение данных 75

Статья Программист Нет файла v8 v8::Запросы 1cv8.cf Бесплатно (free) Практика программирования

В статье приведены особенности внутренней архитектуры и примеры работы с расширением языка запросов 1С.

01.06.2018    22379    m-rv    21       

Строим графы средствами 1С (без GraphViz) 43

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Множество статей на Инфостарте описывают, как работать с компонентой GraphViz, чтобы построить ориентированный граф. Но практически нет материалов, как работать с такими графами средствами 1С. Сегодня я расскажу, как красиво строить графы с минимальным пересечением. Нам этот метод пригодился для отрисовки алгоритмов в БИТ.Финансе, т.к. типовой механизм не устраивал. Еще это может быть полезно для визуализации различных зависимостей: расчета себестоимости, графы аффилированности компаний и т.д. Надеюсь, эта статья поможет сделать мир 1С красивее и гармоничней:) Итак, поехали...

23.05.2018    18156    slozhenikin_com    19       

Распределение расходов пропорционально продажам 9

Статья Программист Пользователь Нет файла v8 v8::ОУ УТ10 УУ Финансовый учет и бюджетирование (FRP) Учет доходов и расходов Бесплатно (free) Практика программирования

Финансовая модель. Распределение административных расходов по подразделениям пропорционально продажам за месяц. Дополнительные реквизиты против бизнес-процессов!

13.05.2018    12183    Rustig    9       

Просмотр временных таблиц запроса в отладчике без изменения кода 130

Статья Программист Нет файла v8 v8::Запросы 1cv8.cf Бесплатно (free) Практика программирования

Данный способ можно использовать для просмотра содержимого временных таблиц запросов (менеджеров временных таблиц) без внесения изменений в код.

24.04.2018    26841    avfed@rambler.ru    19       

Минимализмы 3 356

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Универсальные функции

Очередная серия "минимализмов" [http://infostart.ru/public/306536/, https://infostart.ru/public/460935/]. Также, как и в предыдущих статьях, здесь приведена подборка коротких оригинальных авторских решений некоторых задач. Ранее эти решения были разбросаны по моим комментариям к чужим публикациям.

19.02.2018    37369    ildarovich    44       

Этюды по программированию. Взаимодействие с Microsoft Word 109

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

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

11.12.2017    26711    milkers    23       

Метод формирования движений в типовых регистрах нетиповыми регистраторами 31

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

Вариант решения задач с проведением по типовым регистрам нетиповыми регистраторами. Зачем - чтобы при сравнении конфигурации не обращать внимание на свойства регистров и исключить вероятность допущения горькой оплошности при обновлении информационных баз, заменив типы регистраторов основной конфигурации типами конфигурации поставщика. Для программных продуктов, имеющих в своем составе метаданных документ "Корректировка регистров"("Корректировка записей регистров").

05.12.2017    22121    itriot11    34       

1С: Конвертация данных 3. Инструкции и примеры. EnterpriseData (универсальный формат обмена) 738

Статья Программист Нет файла v8 КД Бесплатно (free) Перенос данных из 1C8 в 1C8 Практика программирования Обмен через XML

Что такое КД3? Как начать использовать? Полезные дополнения к документации. Что нужно исправить в типовых обработках и конфигурации. Как изменить правила обмена не снимая конфигурацию с поддержки. Как отлаживать правила обмена?

19.11.2017    143465    MaxS    251       

Заполнение данных по ИНН контрагента с помощью альтернативного сервиса огрн.онлайн 131

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Код для заполнения данных по ИНН контрагента из ЕГРЮЛ с сайта огрн.онлайн.

01.11.2017    23970    slava_1c    49       

Программные перечисления, ч.2: приемы кэширования при разработке 67

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

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

30.10.2017    22229    unichkin    18       

Разбираемся с настройками компоновки данных 161

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Краткая шпаргалка по программной работе с настройками СКД

29.10.2017    25358    json    9       

Работа с Excel 299

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Загрузка и выгрузка в Excel

Собрал различные полезности для работы с Excel из 1С. Иногда приходится форматировать документ Excel программно из 1С. Так вот, чтобы не искать постоянно на просторах интернета как сделать левое выравнивание в ячейке Excel из 1С и т.п. решил опубликовать это...

23.10.2017    27469    arakelyan    39