0. dmurk 194 11.06.19 17:00 Сейчас в теме

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

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

Перейти к публикации

Комментарии
Избранное Подписка Сортировка: Древо
1. bulpi 150 11.06.19 18:45 Сейчас в теме
Статья полезная, хотя некоторые приемы программирования спорны. Но это дело вкуса.
12. dmurk 194 12.06.19 14:00 Сейчас в теме
(1) Приходите на конференцию Инфостарт 2019, обсудим ))
2. GeraltSnow 80 11.06.19 18:56 Сейчас в теме
Статья впечатляет. Чем больше нового узнаю, тем больше понимаю, что ничего не понимаю.
13. dmurk 194 12.06.19 14:00 Сейчас в теме
(2) В этом году планирую продолжение
3. AlexandrSmith 24 11.06.19 23:29 Сейчас в теме
Отличная статья. Все буквально, все приемы из неё использовал, и точно могу сказать, что на практике все именно так и есть. Моя искренняя благодарность автору за хорошую статью. Правда, что-то подобное видел на английском языке, но не так красиво и доходчиво структурировано как здесь. Если это и перевод, то дополненный отличным пониманием вопроса.
10. dmurk 194 12.06.19 13:57 Сейчас в теме
(3) Это не перевод )) Это боль из жизни
41. AlexandrSmith 24 13.06.19 00:21 Сейчас в теме
(10)
Тем более статья отличная.
4. unichkin 1163 12.06.19 02:45 Сейчас в теме
Доброго времени. Так вышло, что совсем недавно пытал профайлер, пытаясь понять работает ли индекс ВТ при условии типа
(Измерение1, Измерени2) В (ВЫБРАТЬ ВТ.Измерение1, Измерение2 ИЗ ВТ КАК ВТ)
У меня так вышло, что индекс не окупается.
Мой тест


Это противоречит вашей рекомендации индексировать поля ВТ. Могли бы подсказать пример, чтобы убедиться в его эффективности?
Прикрепленные файлы:
5. Fox-trot 99 12.06.19 08:29 Сейчас в теме
(4) попробуй в конфигураторе поменять местами измерения МестоХранения и Раздел, если это самый частый запрос
если нет, то можно попробовать добавить отедльный индекс(ы)
36. unichkin 1163 12.06.19 23:18 Сейчас в теме
(5)
(4) попробуй в конфигураторе поменять местами измерения МестоХранения и Раздел, если это самый частый запрос

Да это просто тест, чтобы проверить. Поможет ли индекс ВТ в этой ситуации, или нет. Судя по ответам я сделал правильные выводы.
11. dmurk 194 12.06.19 13:59 Сейчас в теме
(4) Заниматься созданием индексов имеет смысл только если вы не располагаете tempdb на медленных дисках. У меня для tempdb используется Intel Optane 118 Гб с латентностью 8 микросекунд.
14. dmurk 194 12.06.19 14:14 Сейчас в теме
(4) Пример запроса. 56 тысяч записей - с индексированием запрос 510 мс, без индексирования - 450 мс
Прикрепленные файлы:
starik-2005; +1 Ответить
40. unichkin 1163 12.06.19 23:37 Сейчас в теме
(14) Не понял ваш пример. Это же просто выборка? Здесь какой смысл в индексах? Не вижу отбора.
45. dmurk 194 13.06.19 06:38 Сейчас в теме
(40) Здесь индексы необходимы для того, чтобы дальнейшие левые соединения с этой временной таблицей не тормозили
47. unichkin 1163 13.06.19 10:04 Сейчас в теме
(45) В (4) я не имел в виду левые соединения. С ними понятно все. Я хочу для себя решить раз и навсегда - нужен ли индекс по полям отбора в этом конкретном примере.
61. dmurk 194 13.06.19 13:16 Сейчас в теме
(47) Думаю, это серьезно зависит от размера временной таблицы. Ориентируйтесь на 8 килобайт / ширину строки временной таблицы в байтах. Если у вас вся ВТ маленькая и помещается на одну страницу, то любое обращение к ВТ всегда грузит её в память SQL сервера целиком
24. dmurk 194 12.06.19 14:48 Сейчас в теме
(4) У вас в принципе нет необходимости во временной таблице в вашем примере. Используйте данные напрямую:

"ВЫБРАТЬ
| ДенежныеСредстваВУОстатки.Портфель КАК Портфель,
| ДенежныеСредстваВУОстатки.МестоХранения КАК МестоХранения,
| ДенежныеСредстваВУОстатки.Раздел КАК Раздел
|ИЗ
| РегистрНакопления.ДенежныеСредстваВУ.Остатки(
| ,
| (Портфель, Раздел) В
| (&ТаблицаОтбора)
| ) КАК ДенежныеСредстваВУОстатки"
Запрос.УстановитьПараметр("ТаблицаОтбора", ТаблицаОтбора.Скопировать( , "Портфель, Раздел"));
unichkin; +1 Ответить
37. unichkin 1163 12.06.19 23:19 Сейчас в теме
39. unichkin 1163 12.06.19 23:35 Сейчас в теме
(24)
| (&ТаблицаОтбора)

И у меня не вышло использовать таблицу значений, как вы это показываете.

Запрос.Текст = "ВЫБРАТЬ
| ДенежныеСредстваВУОстатки.Портфель КАК Портфель,
| ДенежныеСредстваВУОстатки.МестоХранения КАК МестоХранения,
| ДенежныеСредстваВУОстатки.Раздел КАК Раздел
|ИЗ
| РегистрНакопления.ДенежныеСредстваВУ.Остатки(, (Портфель, Раздел) В (&ТаблицаОтбора)) КАК ДенежныеСредстваВУОстатки";

{ВнешняяОбработка.Тест.Форма.Форма.Форма(49)}: Ошибка при вызове метода контекста (Выполнить)
РезультатЗапроса = Запрос.Выполнить();
по причине:
{(6, 68)}: Неверные параметры в операции сравнения. Нельзя сравнивать поля
неограниченной длины и поля несовместимых типов.
РегистрНакопления.ДенежныеСредстваВУ.Остатки(, (Портфель, Раздел) <<?>>В (&ТаблицаОтбора)) КАК ДенежныеСредстваВУОстатки
____________________________
Запрос.Текст = "ВЫБРАТЬ
| ДенежныеСредстваВУОстатки.Портфель КАК Портфель,
| ДенежныеСредстваВУОстатки.МестоХранения КАК МестоХранения,
| ДенежныеСредстваВУОстатки.Раздел КАК Раздел
|ИЗ
| РегистрНакопления.ДенежныеСредстваВУ.Остатки(
| ,
| (Портфель, Раздел) В
| (ВЫБРАТЬ
| ТО.Портфель,
| ТО.Раздел
| ИЗ
| &ТаблицаОтбора КАК ТО)) КАК ДенежныеСредстваВУОстатки";

{ВнешняяОбработка.Тест.Форма.Форма.Форма(49)}: Ошибка при вызове метода контекста (Выполнить)
РезультатЗапроса = Запрос.Выполнить();
по причине:
Содержимое объекта данных может быть выбрано только во временную таблицу
44. dmurk 194 13.06.19 06:36 Сейчас в теме
(39) У тебя проблема с ограничениями типов в колонках возвращаемой таблицы. Потому и индексирование не эффективно либо используй ВЫРАЗИТЬ( ) для индексируемых полей переданной таблицы, либо не ленись при создании таблицы значений указывать ограничения типов
Прикрепленные файлы:
49. unichkin 1163 13.06.19 10:25 Сейчас в теме
(44) действительно, с типами были проблемы. Эту таблицу я получал выгрузкой из запроса, при этом в описании типов колонки присутствует NULL. Не думал что сработает, спасибо.
51. dmurk 194 13.06.19 11:11 Сейчас в теме
87. nicxxx 226 14.06.19 11:19 Сейчас в теме
(4)
вместо "Просмотр строк таблицы" появился "Clustered index scan" - а это для ВТ по сути то же самое: раньше просматривались строки таблицы, теперь индексы этих строк. Это потому что в ней комбинации значений уникальны, либо близки к уникальным - количество значений индекса равно количеству строк.

Насчет изменения сущности написано не совсем верно, вот здесь:
теперь индексы этих строк
- кластерный индекс это и есть таблица, упорядоченная по полям индекса, поэтому технически ничего не поменялось - просматривается та же таблица.
88. unichkin 1163 14.06.19 11:25 Сейчас в теме
(87)
- кластерный индекс это и есть таблица, упорядоченная по полям индекса, поэтому технически ничего не поменялось - просматривается та же таблица.

Спасибо! Да, я это и имел в виду.
6. serg_gres 139 12.06.19 09:35 Сейчас в теме
Многоуважаемый автор, статья называется "Многопоточное ускорение однопользовательских нагрузок в 1С + Microsoft SQL Server 2017",
в статье много десятков станиц со скриншотами и диаграммами, а про многопоточность и, связанное с этим ускорение, написано в самом конце менее 10 строк.
При чем написано абсолютно не понятно что. Какие еще программа генерирует видео - примитивы ? О чем это ?
Абсолютно не понимаю как время открытия рабочего стола было 15 минут и после запуска 15 фоновых заданий стало 0,3 секунды.
Что это за фоновые задания ? Что они выполняли ? За счет чего произошло ускорение ?
Если 15 фоновых заданий распараллелили нагрузку, то почему время открытия стало не 1 мин, а 0,3 сек ?
В стате очень много информации не относящейся к заданной заголовком теме, в про саму тему не написано по сути ничего.
mivari; unichkin; a_titeev; Dream_kz; Xershi; +5 Ответить
9. Xershi 624 12.06.19 10:47 Сейчас в теме
(6) я так понял там было одно фоновое задание, а возможно серверный код, который они распаралелили на порции и запустили в 15 потоков. Как итог серверного кода нету и данные в фоне получаются со временем, а 0.3 это фикция скорее всего визуальный эффект для пользователя не более.
17. dmurk 194 12.06.19 14:23 Сейчас в теме
(9) Вы не совсем правы. Эта "фикция" с января 2019 доступна штатными объектами 1С в корпоративной редакции платформы
18. Xershi 624 12.06.19 14:27 Сейчас в теме
(17) а я не говорил что это истина. Это лишь предположение, которое должен автор либо подтвердить либо опровергнуть.
Либо другой специалист, который понял и реализовал, то о чем говорил автор.
Вы я так понял немного в теме. Вы и есть автор)))
15. Dach 240 12.06.19 14:17 Сейчас в теме
(6) тоже очень интересно про ускорение открытия формы рабочего стола. Что конкретно там засунули в фоновые обработчики? Автор, можно код в студию?
22. dmurk 194 12.06.19 14:42 Сейчас в теме
(15) кода там 4771 строк запроса данных у СУБД, 866 строк запуска и обработки результатов фоновых заданий, и 8568 строк постобработки результатов на клиенте в вариантах исполнения Тонкий клиент, Веб клиент.

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

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

выложить код нельзя, это конфиденциально
16. dmurk 194 12.06.19 14:21 Сейчас в теме
(6) Продолжение доклада снято в другом зале.

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

б) Правильно настраивайте кластер 1С, иначе получите работу фоновых заданий не параллельную, а последовательную.

Разделяйте вычислительные задачи к СУБД на несколько фоновых заданий - и получите ускорение, если выполнены условия а) и б)
57. DarkAn 808 13.06.19 12:32 Сейчас в теме
(16)
покупайте лицензии

Это действительно необходимо? я с точки зрения, что скуль ими оперирует при работе с базой?

Где то можно посмотреть текущее состояние по лицензиям (правда скуль у нас староват 2008R2). ?

И еще вопрос, в докладе вы сказали, что tempdb не стоит класть на RAM - почему?


Дмитрий, спасибо за доклад.
64. starik-2005 1852 13.06.19 13:24 Сейчас в теме
(57)
tempdb не стоит класть на RAM - почему?
Я бы тут два отметил момента:
1. Памяти много не бывает, зачем ее засирать еще и временными таблицами, которые в 1С при достаточном количестве пользователей выкушают ее сколько бы ее ни было. Исходя из этого стоит их заснуть на быстрый диск, т.к. они все равно до кучи еще кешируются ОСью. Т.е. засунем в ОЗУ - и это у нас двойной расход ОЗУ.
2. Подумал о надежности, но понял, что смысла для надежности держать временные таблицы вне памяти нет никакого.
70. dmurk 194 13.06.19 15:43 Сейчас в теме
(57) Количество параллельных потоков а) вычислительных б) дисковых в плане выполнения любого запроса ограничено сверху количеством установленных лицензий. Не распространяется на вычислительные/дисковые операции в tempdb.

Посмотреть количество лицензий вы можете при скачивании вашего экземпляра SQL с сайта Microsoft. Из вашего кабинета пользователя раздается инсталляция SQL с вашим количеством лицензий.

SQL 2008R2 рекомендую забыть, даже на старых серверных ОС можно впихнуть SQL 2014, если ОС новая, то SQL 2017.

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

Большинство драйверов RAM имеет серьезные проблемы производительности, что делает их более медленными чем NVMe накопители. Кроме того, дисковый кэш в памяти может решать те же задачи, а вот задачу когда закончилось место на RAM диске вы решить не сможете.
76. DarkAn 808 13.06.19 17:13 Сейчас в теме
(70)
Из вашего кабинета пользователя

Тут проблема, наша организация под санкциями :) Личный кабинет недоступен :(

Тем более это же в облаке, а на сервере как посмотреть?

(70)
SQL 2008R2 рекомендую забыть, даже на старых серверных ОС можно впихнуть SQL 2014

Это было бы да, но надо покупать, а это опять п.1

(70)
задачу когда закончилось место на RAM диске вы решить не сможете

Почему? Можно же сделать 2 файла, один в рам, другой на физике.
Дмитрий Юхтимовский рассказывал, что для того чтобы использование было с приоритетом в РАМ, необходимо ему задать объем больше чем физике, например, 1 к 100, кроме того задать ограничение на объем.
79. dmurk 194 13.06.19 17:43 Сейчас в теме
Тем более это же в облаке, а на сервере как посмотреть?

Зайдите в ручную настройку processor affinity. Укажите ручное распределение. Начните расставлять флажки. В момент когда SSMS выругается вы поймете что лицензии закончились. Если нигде не выругалось, скорее всего у вас триал на 1 поток.

Это было бы да, но надо покупать, а это опять п.1

Developer Edition бесплатный. Enterprise Edition без проблем покупается через Минск.

Почему? Можно же сделать 2 файла, один в рам, другой на физике.

Практика показывает, что другие типы дисков работают с аналогичной скоростью либо тупо быстрее. Во вложении пример скорости бесплатного драйвера RAM-disk. При этом скорость решения сложных задач даже на оптимизированном драйвере значительно повысится только при выделении значительных объемов памяти. Мне, например, выделить 128 Гб DDR4 ОЗУ под RAM диск - это потратить на это дополнительные 800$, а задействовать Optane - всего 300$.

пример:
AVAGO SAS RAID контроллер LSI MegaRAID SAS 9361-4i +16 Gb Cache Vault
- Скорость чтения из кеша 4,0 Gb/сек // Скорость записи в кеш 7,8 Gb/сек // 112 тысяч IOPS
SSD диск INTEL Optane 800P 118 Гб SSDPEK1W120GA01 M.2 PCI-Express - 145 тысяч IOPS на 4К блоках (1132 Mb/сек на 8-кб страницах) именно его всем рекомендую под tempdb в качестве основного файла, т.к. латентность 8 микросекунд. Построение индексов на таком диске проходит абсолютно безболезненно, что и позволяет извращаться по остальным направлениям.
SSD диск Samsung 960 PRO 2 Тб MZ-V6P2T0BW M.2 PCI-Express - 360000 IOPS (3,5 Gb/s чтение из СУБД)
Прикрепленные файлы:
28. dmurk 194 12.06.19 15:13 Сейчас в теме
(6) Опечатка при наборе доклада на основании видео. В докладе рассматривалось две задачи:

1. Проведение большого документа. Распараллеливание позволило добиться 15:00 мин -> 2:20 мин
2. Открытие рабочего стола. Распараллеливание и рефакторинг позволило добиться 15 сек -> 0,3 сек
62. DarkAn 808 13.06.19 13:17 Сейчас в теме
(28) Распараллеливание документа??? Это как? А транзакция?
63. dmurk 194 13.06.19 13:18 Сейчас в теме
(62) Решено! ))

Голосуйте за мой новый доклад - в сентябре расскажу.
7. starik-2005 1852 12.06.19 10:07 Сейчас в теме
За эпик от красных отдельный плюс))) И, кстати, у него за 750 баксов 8 каналов памяти, в интелах только в самых дорогих 12, в попроще - за 3к - 6.
26. dmurk 194 12.06.19 14:57 Сейчас в теме
(7) 12 канальные интел - это та ещё фикция. У них между сокетами используется PCI express x4 третьей версии в каждом направлении. А это всего 3,8 ГБ/с. Никогда не видели, как во время бакапа СУБД на четырехсокетных Intel'ах терминалы в виртуалках виснут? )))
8. Xershi 624 12.06.19 10:42 Сейчас в теме
На картинке "Привязка кода 1С к дискам" мне кажется ошибка в написании кода?)
Или в чем смысл такой многоходовки?
19. dmurk 194 12.06.19 14:28 Сейчас в теме
(8) Смысл в том что фоновое задание на сервере имеет один входящий параметр - идентификатор временного хранилища, обращается к СУБД, получает и обрабатывает данные, после чего результат обработки отдается через временное хранилище обратно на клиент
20. Xershi 624 12.06.19 14:29 Сейчас в теме
(19) у вас 2 картинки названы одинаково. Я про первую!
21. dmurk 194 12.06.19 14:33 Сейчас в теме
(20) Дело в том что на большом экране во время доклада многострочный код практически нечитаем, поэтому это выдернутая из контекста иллюстрация показывающая разницу в дисковой нагрузке от двух разных методов. Метод результата запроса "Выбрать" складывается на диск в каталог SRVINFO, а метод "Выгрузить" перекладывается из окна доступа к памяти SQL (shared memory) в память кластера 1С. Из-за этого эффекта даже на сверхмалых таблицах можно внезапно получать +200 мс к выполнению запроса
23. Xershi 624 12.06.19 14:45 Сейчас в теме
(21) теперь стало понятно, что это не опечатка. но тогда другой вопрос. На малых таблицах все пойдет в память, а что тогда для сверх больших? Тогда будет огромный расход памяти и возможно при нехватке еще большее замедление?
25. dmurk 194 12.06.19 14:49 Сейчас в теме
(23) Конечно замедление возможно. Пример дан с целью того, чтобы подтолкнуть слушателей осознанно принимать решение об использовании Выбрать или Выгрузить
27. Xershi 624 12.06.19 15:04 Сейчас в теме
(25) Я всегда использую выбрать. Сомнительный выигрыш в скорости по сравнению с дырой в памяти.
Но если очень нужно, то как вариант ускорения сойдет.

Точнее не всегда, а в большинстве случаев. Когда нужно получить ТЗ, то выбрать не использую.
29. acanta 55 12.06.19 16:49 Сейчас в теме
(27) правильно ли я понимаю, что таблицу значений в 8ке нельзя использовать из за размещения их в оперативной памяти без освобождения при обнулении переменной?
30. Sashares 17 12.06.19 17:27 Сейчас в теме
(29)Память освобождается по завершению процедуры, в которой обнулили переменную, а не в момент обнуления.
31. dmurk 194 12.06.19 19:38 Сейчас в теме
(29) таблицу значений использовать можно и нужно. особенно с индексами
32. starik-2005 1852 12.06.19 20:46 Сейчас в теме
(31) както коллега тестил поиск по индексированной ТЗ (не путать с ВТ) - до 100 позиций был проигрыш по сравнению с неиндексированной, что меня несколько удивило
33. dmurk 194 12.06.19 22:12 Сейчас в теме
(32) Если вы в таблицу значений добавили индексы по полям "Номенклатура, СерияНоменклатуры, Склад" а поиск выполняете по структурам "Номенклатура, Характеристика", то индекс работать не будет.

Что это означает. Если вы ищете по ТЗ разными структурами отбора, в индексах у вас должен присутствовать каждый вариант набора искомых полей по которым будет выполняться поиск.

Индексы.Добавить("Номенклатура")
Индексы.Добавить("Номенклатура, Характеристика")
Индексы.Добавить("Номенклатура, Характеристика, Склад")

и гэтак далей ))

Кроме того, при аппаратной поддержке инструкций хэширования вашим процессором, индексация таблицы будет занимать менее 1% времени её заполнения, а на старых процессорах может доходить и до 30%.
35. starik-2005 1852 12.06.19 23:17 Сейчас в теме
(33) америку открыл)))

По поводу аппаратных инструкций, то разные алгоритмы хеш не только мд5 и подобные делают - там все иначе. И поиск хеша при мд5 - это выборка с О(лог2н), равнозначная поиску в любом упорядоченном списке. Хнш джоин использует другого уровня хеш, который у Макконнелла описан как табличная оптимизация - это обычно 16-24 битное целое, а все эти аппаратные хеши - это куда больше бит и их в приемлемой величины память уже не упаковать.

Да, Вы всегда можете рассказать нам, как это все работает "на самом деле" и про аппаратный расчет хеша, и где оно там юзается. Было бы интересно ознакомиться с Вашими соображениями и заметить в них неточности)))
34. dmurk 194 12.06.19 22:13 Сейчас в теме
Специально для тех кому не хватило доклада, выкладываю стенограмму окончания доклада в прикрепленном файле.
Прикрепленные файлы:
Многопоток продолжение.txt
e][tend; serg_gres; acanta; +3 Ответить
68. e][tend 13.06.19 15:08 Сейчас в теме
(34) Дмитрий, спасибо за доклад и стенограмму. Правда из нее не совсем понял момент связанный с тонкими клиентами, которые с кешем 4 уровня. Я правильно вас понимаю, что вы клиентов пересадили на тонкие клиенты и они у вас подключались сразу к серверу 1С?
Если да, то такой вариант именно на этом процессоре, получается производительней, чем RDP сессия на вирт. сервак, с которого выполняется подключение к серверу 1С?
69. dmurk 194 13.06.19 15:32 Сейчас в теме
(68) Всё верно. Достижение максимальной производительности является совокупностью решений
38. starik-2005 1852 12.06.19 23:28 Сейчас в теме
Кстати, на тему недостатков хеш джоина:
Условием соединения может быть только равенство.Большая потребность в памяти для построения хеш-таблицы, что крайне ограничивает масштабируемостьалгоритма при увеличении размеров меньшей таблицы.Хеш-таблица должна быть построена полностью, до того как первый результат будет записан в результирующую таблицу, что делает этот вид соединения неприемлемым при необходимости получить первую строку результата как можно быстрее.
42. dmurk 194 13.06.19 06:26 Сейчас в теме
(38) Думаю, это отличный вопрос для простого исследования
43. dmurk 194 13.06.19 06:30 Сейчас в теме
(38) В ситуациях когда необходимо работать со случайно расширяемыми данными незначительного объема, я использую соответствия, могу использовать один или два раза вложенные структурами. Это решает в первую очередь вопрос быстрого нахождения строки в списке, в которой необходимо отразить изменение данных
48. starik-2005 1852 13.06.19 10:24 Сейчас в теме
(43) а есть информация о том, как работает соотвветствие со стороны 1С? Лично мне думается, что соответствие - это мемсет, который является упорядоченным хрантлищем ключей и соответствующих им значений. Ключ нормализуется хеш-функцией, дальше поиск и вставка за логарифм по основанию 2 из размера - это вполне себе быстро.
Но как быть со скулом? Там соединение берет малую таблицу, к ней берет хеширующую таблицу на 16 бит, например, - это 64*4=256 килобайт сразу, забивает ее пространство нулями и указателями на элемент, а если хеш получается с коллизией, то и на кортеж элементов, дальше пробегается по второй таблице и сравнивает 16-битный хеш от полей на равенство с ячейкой в 256 кб и если там 0 - идет дальше, а если указатель - берет его и смотрит, кортеж там или элемент. Дальше происходит сравнение ключей, т.к. во второй таблице хеш тоже может получиться с колизией. И если они равны (ключи) - тогда результат идет в результирующую выборку.

Теперь вопрос: где здесь 30% при отсутствии аппаратного хеширования и что за функция такая аппаратная (мнемоника ассемблерная) используется?
50. dmurk 194 13.06.19 11:06 Сейчас в теме
(48) Со скулом работа индексов и хешей исчерпывающе объяснена здесь https://docs.microsoft.com/en-us/sql/relational-databases/sql-server-index-design-guide?view=sql-server-2017. В блогах инженеров натыкался на пояснения, что при аппаратной поддержке hash алгоритмов, используется аппаратный расчет хешей.

30% - это на собственном опыте. В феврале 2011 года от известной в 1С команды поступила задача на оптимизацию медленного ссылочного склеивания 19-ти таблиц документов в 1С: Документооборот в виде ВЫБРАТЬ Ссылка ИЗ ... ОБЪЕДИНИТЬ ВЫБРАТЬ Ссылка ИЗ ... и т.п.
Одним источником проблемы было наличие конструкции ОБЪЕДИНИТЬ вместо ОБЪЕДИНИТЬ ВСЕ в тексте запроса, вторым - виртуализация среды с маскировкой версии процессора, третьим - то что это все крутилось на чем-то очень древнем с частотой 2,4 Ггц.

Как итог - запрос выполнялся 45 секунд когда поступил мне, и 1,5 секунды когда был отдан обратно.
55. starik-2005 1852 13.06.19 11:34 Сейчас в теме
(50) ну 1.5 сек против 45 - это не 30%. 30% - это 0.5 сек от 1.5 сек. Так что это не объяснение.

А по поводу аппаратной поддержки хеша, то тут системы с шифрованием показывают хорошую овер 2 раза производительность на шифровании и расшифровке, что, кстати, у АМД работает даже в однопотоке быстрее, чем у штеуда.

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

Зы: сдается мне, что даже пилильщики 1С-ного ядра толком не понимают, как это работает, поэтому вся их оптимайз основана на технологии try-repeat..
58. dmurk 194 13.06.19 12:46 Сейчас в теме
(55) 45 секунд делим на 18 объединений 19-ти таблиц, получаем 40% увеличение времени на одном объединении
65. starik-2005 1852 13.06.19 13:41 Сейчас в теме
(58)
18 объединений 19-ти таблиц
Ну а как Вы себе представляете хеш-джойн этих 19-ти таблиц?

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

Если предположить, что скул писали не совсем долбики, то можно подумать, что они написали как-то так:
1. Берем самую маленькую таблицу и делаем из нее хеш-таблицу по совокупности ключей (у нас тут объединение, а не соединение, поэтому все поля участвуют).
2. Соединяем ее со второй таблицей. Из непопавших в хеш записей делаем новые кортежи.
3. Идем к пункту 1, убрав из него вторую таблицу (ну и первую тоже).

Даже при таком раскладе количество посчитанных хешей равно количеству строк во всех таблицах. И, предположим, новый алгоритм ускоряет на 30% расчет хешей, это приведет к тому, что общий итог должен быть равен 45 сек - 30% = 30 сек (и это только в том случае, что процессор древний у нас ничего кроме хешей не считает). А у нас 1,5 сек, да? К какому выводу приходим? У меня их ровно два: с Вашей точки зрения получается, что создатели скула те еще долбики и считают хеши в изначальном варианте с апаратно-недееспособным сервером не на 30% больше времени, а на 3000% (в 30 раз). Но как? Они в том и другом случае считают хеши одинаковое количество раз (надеюсь Вы понимаете, почему?) - и это по Вашему же утверждению должно повысить производительность только на 30%, откуда здесь 3000%? Второй вариант - это аппаратная виртуализация, отсутствие которой действительно может затормозить систему в овер 10 раз, но и то весьма сомнительно, т.к. паравиртуализация и динамическая трансляция, как основные средства программной виртуализации, тормозят систему ну может раза в два-три - не более, хотя включение аппаратной работы с памятью хоста из виртуальной машины способно значительно, как пишут в документации к ВМ, повысить производительност guest-систем, но, опять же, не на 3000%.
66. dmurk 194 13.06.19 14:03 Сейчас в теме
(65) К сожалению, повторить тот давний опыт я не в состоянии. Но именно он меня подтолкнул от программирования 1С перейти к изучению работы SQL
67. starik-2005 1852 13.06.19 14:10 Сейчас в теме
(66)
от программирования 1С перейти к изучению работы SQL
С/С++ спасет отца русской демократии, ибо там, конечно, есть map, но он реализован на С/С++, а не на языке 1С )))
84. dmurk 194 14.06.19 00:41 Сейчас в теме
(65) проверил идею как что работает:

При первом выполнении плана запроса каждая таблица, которая написана с маркером ОБЪЕДИНИТЬ замедляет выполнение запроса на время необходимое для хеширования измерений всех строк из всех источников

При повторных выполнениях плана запроса берется кеш таблиц из ОЗУ вместе с уже посчитанными хешами, а общее время выполнения запросов считается как общий объем в мегабайтах результирующей таблицы деленный на ПСП.

Так как в моем примере существует частичное слияние результатов, то для повторных запусков быстрее отрабатывает ОБЪЕДИНИТЬ, а для первых - ОБЪЕДИНИТЬ ВСЕ.
Прикрепленные файлы:
59. dmurk 194 13.06.19 12:47 Сейчас в теме
(55) Пилильщики 1С-ядра несколько раз 100% поменяли штатный состав за 10 лет.
60. acanta 55 13.06.19 12:51 Сейчас в теме
(59) Огромная благодарность за доклад и автору и комментаторам. Нашла ответы на очень многие вопросы.
56. starik-2005 1852 13.06.19 11:53 Сейчас в теме
(50) кстати, чрезвычайно интересная статейка и там даже есть слово "30%" - вот оно:
If two index keys are mapped to the same hash bucket, there is a hash collision. A large number of hash collisions can have a performance impact on read operations. A realistic goal is for 30% of the buckets contain two different key values.
Но это, конечно, о другом)))
53. dmurk 194 13.06.19 11:15 Сейчас в теме
(48) со стороны 1С соответствие воспринимается как какая-то коллекция, которая используется для быстрого доступа к значениям по ключам. В C# есть полный аналог - IDictionary.
54. starik-2005 1852 13.06.19 11:26 Сейчас в теме
(53) и все это по факту сбалансированные деревья.
46. asved.ru 36 13.06.19 07:50 Сейчас в теме

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

Но оно выполняется далеко не для любой глубины вложенных запросов. Поэтому вам рекомендуют их не использовать. Если вы сделаете 3-4 уровня вложенности, наследование индексов работать перестанет.


Что это за бред? Зачем вы выдумываете несуществующие термины?
Откройте для себя такие вещи, как план запроса, операции sort и merge join в нем. В описанном примере, читая индекс, оптимизатор понимает, что выборка из него будет упорядочена по ключевым полям, как следствие цена sort + merge join будет ниже, чем hash join, т.к. sort не требуется.

Вложенный запрос может отрабатывать быстрее в тех случаях, когда оптимизатору удается построить для него достаточно хороший план, экономия возникает на отсутствии ожиданий tempdb. Грубо говоря, tempdb - это костыль, применяемый когда данные в основной БД лежат настолько неудобно для нашего запроса, что их проще перекомпоновать.

PS TSQL - не императивный, а описательный язык. Сервер СУБД делает не то, что Вы написали в запросе, а то, что сам решит нужным для получения затребованного вами результата. А до сервера еще есть движок SDBL, который тоже зачастую делает не совсем очевидные вещи. Поэтому в терминах текста запроса на BSL говорить о его производительности имеет смысл только в формате стандарта "так делать нельзя".
52. dmurk 194 13.06.19 11:12 Сейчас в теме
(46) Вся платформа 1С с точки зрения sql.ru это один большой несуществующий термин ))

Когда я начинал изучать программирование в 1986-м, терминология которую вы в данный момент используете ещё не была придумана, а документ ANSI X3.135-1986 не содержал даже приблизительных упоминаний о HASH JOIN.

Однако реляционные СУБД уже существовали и слово "наследование" было понятно моим собеседникам.
72. asved.ru 36 13.06.19 16:04 Сейчас в теме
(52)
документ ANSI X3.135-1986 не содержал даже приблизительных упоминаний о HASH JOIN


В T-SQL нет термина hash join. От слова совсем.


(52)
и слово "наследование" было понятно моим собеседникам

Может быть, это о том наследовании, которое с инкапсуляцией и полиморфизмом? :) Ну так выборка из таблицы - это не объект класса, а набор данных, структурированный определенным образом.
А индекс - это физическая таблица, из которой выбираются данные. Причем практически для всех объектов 1С существует индекс, хранящий вообще все данные таблицы, и не существует кучи. Выборка может наследовать порядок индекса. А может и не наследовать. Но не сам индекс.

Более того, возьмем три запроса:

sel ect * fr om table where A and B
и
sel ect * fr om (sel ect * fr om table where A) where B
и
sel ect * fr om (select * fr om table where B) wh ere A


и посмотрим на их планы - они окажутся идентичны.
74. dmurk 194 13.06.19 16:08 Сейчас в теме
(72) Для того чтобы вам оппонировать, необходимо дополнительное исследование вопроса, в данный момент не готов ответить
81. starik-2005 1852 13.06.19 17:54 Сейчас в теме
(74)
необходимо дополнительное исследование вопроса
В транзакционном SQL (т.е. T-SQL), и в любом другом ANSI SQL и т.д. нет hash join, там есть left/right*inner/outer/full join. Но это SQL. Дальше есть работа с данными, их выборки, объединения, соединения и вся прочая муть на уровне системы. И вот там есть понятия hash join, nested loops и некоторые другие, которых в SQL нет от слова совсем. Т.е. мы с Вами беседовали об одном, а человеек тут пришел и не нашел поиском в стандарте слов hash и join и принял это за какую-то проблему )))
acanta; dmurk; +2 Ответить
83. dmurk 194 13.06.19 18:05 Сейчас в теме
(81) А ведь он абсолютно прав! Каждый человек выстраивает для себя картину мира, и всё что с ней не совпадает, является проблемой.

Он бы хотел, чтобы на аудиторию в 500 человек был доклад именно с такими терминами. Пытаешься изложить как можно более доступно, получаешь от организаторов замечание о чрезмерной сложности первой версии доклада, а тут бац! Терминология не специфическая ))
85. dmurk 194 14.06.19 01:21 Сейчас в теме
(72) Подумал. Вы не правы.

- в приведенном в докладе примере, виртуальная таблица из которой производится выборка, является не структурированным набором данных, это сущность, которая обладает:
- инкапсуляцией
- полиморфизмом

- что касается наследования, о котором я говорил, то оно работает следующим образом:
- при выборке данных из _виртуальных_ таблиц остатков и оборотов данные попадают в вышестоящую группировку из кластеризованных индексов совместно с предварительно рассчитанными хешами измерений, вследствие чего группировака вышестоящей таблицы по индексируемым измерениям не требует её предварительного хеширования, т.к. эта информация уже существует во вложенном запросе
89. nicxxx 226 14.06.19 11:29 Сейчас в теме
(72)
В T-SQL нет термина hash join. От слова совсем.

Я бы поспорил.
https://docs.microsoft.com/ru-ru/sql/t-sql/queries/hints-transact-sql-join?view=sql-server-2017
91. starik-2005 1852 14.06.19 14:46 Сейчас в теме
(89)
Я бы поспорил.
Да, хинты там есть. А еще они есть в постгресе и конфиге постгреса. Но хинты - это типа такие "помощники" оптимизатора запросов, но в стандарте ANSI SQL не совсем понятно, есть они или нет - он (стандарт) в инете есть за 60 баксоф.
71. V_V_V 13.06.19 15:58 Сейчас в теме
Я что-то упустил или точно нигде не сказано на каком именно релизе 1С:Предприятия всё тестировалось\оптимизировалось?
73. dmurk 194 13.06.19 16:06 Сейчас в теме
(71) Нигде не сказано. Начиналось на 8.3.4. Длилось 1,5 года. Закончилось на 8.3.11
75. V_V_V 13.06.19 16:48 Сейчас в теме
(73)
Также не все знают, что конструкцию ЕСТЬNULL можно использовать прямо в секции условий вместо того, чтобы писать какие-то сложные параметрические условия.

8.3.12.1412 - ругается "Операция не разрешена в предложении..."
77. dmurk 194 13.06.19 17:18 Сейчас в теме
(75) Сложно вам ответить в ситуации когда вы не выкладываете пример. Например вы могли воспользоваться конструктором запроса, который имеет ошибку пересборки условий, или поместили операцию вместо секции ГДЕ в секцию ИМЕЮЩИЕ
82. V_V_V 13.06.19 18:04 Сейчас в теме
(77) Прошу прощения, работает. Само условие в секции ГДЕ неправильно формулировал.
78. Darklight 17 13.06.19 17:30 Сейчас в теме
Очень сложная статья (и видимо сложный доклад) для восприятия теми, кто не в теме хотя бы на 98% - информация очень интересна и порой шокирующая, но не то что совсем не разжёвана, но часто попросту совсем труднопонятна - автор мечется из стороны в сторону, говорит/пишет много слов - но сложить из них реальное представление обсуждаемых процессов и предлагаемых действий к оптимизации - почти нереально. Автор много говорит о том, что надо что-то там настраивать, но очень мало говорит о том, что же надо настраивать (не говоря уже о том – как настраивать). Я конечно понимаю, что доклад был и так не малый, и более детальное повествование туда не запихнуть, но реально - это статья раззадоривает аппетит, но конкретики даёт очень мало - а где хоть немного ясно о чём речь, то почти всегда отсутствуют обоснования и альтернативные рассуждения (а в деле оптимизации одна единственная точка зрения редко бывает верной для большинства случаев). В общем - статья хороша как понимание того, что известная тебе правда не всегда бывает истиной - но из этого не следует что полученная новая правда - тоже является истиной. Иди - и разбирайся с этим самостоятельно - разжёвывать тебе тут не обязаны! Ну, может новый доклад будет попонятнее (и более узкоспециализированный, не пытающийся охватить сразу всё) Интересно, но очень тяжело это всё воспринимать, даже человеку «в теме».
80. dmurk 194 13.06.19 17:49 Сейчас в теме
(78) Задавайте вопросы, с удовольствием разжуём
86. Zlohobbit 111 14.06.19 09:20 Сейчас в теме
Добрый день!
Относительно
...
А когда вы делаете «Выбрать()», результат запроса попадает на диск. Получается, что если вы из запроса хотите выбрать 4 строчки, то кластер 1С сначала запишет весь результат где-нибудь у себя на медленный диск, а потом эти 4 строчки начинает открывать TCP-соединениями и отдавать вашему клиенту
...
Это отчасти правда, только в единственном случае:
Если используется 32-битная версия платформы, и размер результата запроса превосходит размер имеющейся памяти, то данные будут записаны на диск, а затем считаны оттуда в процессе вызовов Выборка.Следующий().
Лучше не делать таких утверждения, так как это потом переносится из "уст в уста"!
Источник:
https://its.1c.ru/db/v8std/content/725/hdoc/_top/%D1%80%D0%B5%D0%B7%D1%83%D­0%BB%D1%8C%D1%82%D0%B0%D1%82%20%D0%B7%D0%B0%D0%BF%D1%80%D0%B­E%D1%81%D0%B0%20%D0%BD%D0%B0%20%D0%B4%D0%B8%D1%81%D0%BA
90. dmurk 194 14.06.19 12:14 Сейчас в теме
(86) Источник недостоверный. Протестировано на толстом клиенте с разрешенными управляемыми формами, версия 8.3.11, 64 битный клиент, 64-битный кластер.
92. Zlohobbit 111 15.06.19 18:39 Сейчас в теме
(90)
Только что проверил procmon'ом на версии 8.3.14.1630 (https://releases.1c.ru/version_files?nick=Platform83&ver=8.3.14.1630).
Как замерял:
- настроил ТЖ (чтобы убедиться, что платформа пишет файлы);
- создал обработку которая выбирает на сервере и обходит записи (Выборка.Следующий()) в цикле;
- открыл procmon на сервере;
- сделал exclude лишних событий, include WriteFile. Фильтр по рабочему процессу;
- что локально, что на другой машине выполнял запрос.

В итоге рабочий процесс кроме ТЖ ничего не писал.
Вопрос, каким образом вы производили замеры? Каким образом заметили такое поведение?
Оставьте свое сообщение
Новые вопросы с вознаграждением
Автор темы объявил вознаграждение за найденный ответ, его получит тот, кто первый поможет автору.

Вакансии

Программист 1С
Бобров
зарплата от 100 000 руб. до 150 000 руб.
Временный (на проект)

Студент (стажер) 1С
Нижний Новгород
зарплата от 25 000 руб.
Полный день

Программист 1С
Санкт-Петербург
зарплата от 120 000 руб.
Полный день

Программист 1С
Нижний Новгород
зарплата до 100 000 руб.
Полный день

Программист 1С
Новосибирск
зарплата от 80 000 руб.
Полный день