Имя: Пароль:
1C
1С v8
Коллеги, ваше мнение. Код такого вид имеет право на жизнь или это говнокод?
0 Галахад
 
гуру
18.02.21
10:46


    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("а", Новый ОписаниеТипов("Булево"));
    Таблица.Колонки.Добавить("б", Новый ОписаниеТипов("Строка"));
    
    НовСтр = Таблица.Добавить();
    НовСтр.а = Истина;
    НовСтр.б = "ббб";
    НовСтр = Таблица.Добавить();
    НовСтр.а = Ложь;
    НовСтр.б = "бббббб";
    
    
    Таблица2 = Новый ТаблицаЗначений;
    Таблица2.Колонки.Добавить("а", Новый ОписаниеТипов("Булево"));
    Таблица2.Колонки.Добавить("г", Новый ОписаниеТипов("Строка"));
    
    НовСтр = Таблица2.Добавить();
    НовСтр.а = Истина;
    НовСтр.г = "ууу";
    
    
    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("Таблица", Таблица);
    Запрос.УстановитьПараметр("Таблица2", Таблица2);
    
    Запрос.Текст =
    "ВЫБРАТЬ
    |    *
    |ПОМЕСТИТЬ ТаблицаДанных
    |ИЗ
    |    &Таблица КАК Таблица
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    *
    |ПОМЕСТИТЬ ТаблицаДанных2
    |ИЗ
    |    &Таблица2 КАК Таблица2
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    *
    |ИЗ
    |    ТаблицаДанных КАК ТаблицаДанных
    |        ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаДанных2 КАК ТаблицаДанных2
    |        ПО ТаблицаДанных.а = ТаблицаДанных2.а";
    
    Таб = Запрос.Выполнить().Выгрузить();
    Таб.Колонки.Удалить("а1");


1 ДенисЧ
 
18.02.21
10:47
2 Fragster
 
гуру
18.02.21
10:48
а нафига тут субд дергать?
3 H A D G E H O G s
 
18.02.21
10:48
Не имеет. Имена колонок и таблиц значений должны четко и однозначно передавать предметную суть.
4 polosov
 
18.02.21
10:49
(3) Не обязательно. Может это одноразовая обработка.
5 Галахад
 
гуру
18.02.21
10:51
Хм. А аргументировать?
6 Галахад
 
гуру
18.02.21
10:51
(2) Это ж пример.
7 Fragster
 
гуру
18.02.21
10:51
(4) обязательно. но, сдается мне, в (0) имена колонок синтетические для примера
8 Галахад
 
гуру
18.02.21
10:58
(7) Конечно. На самом деле Колонок несколько больше, не говоря уж о строках.
9 H A D G E H O G s
 
18.02.21
11:01
Я не понял, что спрашивает автор?
Можно ли соединять таблицы с помощью субд или с помощью сервера 1с?
Я думаю, не стоит использовать субд. Используй код. А в коде либо индексирование одной из таблиц, либо мердж.

Кроме того, SQL регистронезависим при работе со строками.
10 Галахад
 
гуру
18.02.21
11:03
(9) В коде медленнее.
11 Волшебник
 
18.02.21
11:03
говнокод детектед
12 Галахад
 
гуру
18.02.21
11:04
(10) +
Ну или правильнее: в моем коде медленнее.
13 Fragster
 
гуру
18.02.21
11:08
(12) таы просто не умеешь его готовить
14 Garykom
 
гуру
18.02.21
11:11
(0) Науя?
15 Галахад
 
гуру
18.02.21
11:12
(13) Наверное. А как быстрее?
16 Garykom
 
гуру
18.02.21
11:13
(15) Сначала опиши что хочешь и какие граничные условия
Легко может получиться на больших табличках что заипешься ждать пока оно на субд и назад передается
17 ptiz
 
18.02.21
11:14
(15) Покажи код и мы ткнем тебя в колонку, по которой ты не создал индекс. Или ты наименование колонки не указываешь в методе ТЗ.Найти()
18 Bigbro
 
18.02.21
11:15
выглядит довольно бредово.
19 Галахад
 
гуру
18.02.21
11:18
(16) Допустим есть
Таблица1 - колонки
   Справочник1, КоличествоА
Таблица2 - колонки
   Справочник1, КоличествоБ

В каждой по по 5000 записей.
Хочу получить
Таблица3 - колонки
   Справочник1, КоличествоА, КоличествоБ
20 Garykom
 
гуру
18.02.21
11:22
(19) Гыгыгыгы
Сначала слей в одну ТЗ а потом Свернуть()
Но учитывай что в некоторых версиях платформы 1С бага с тормозами если есть в ТЗ ссылки на Справочники и т.д.
21 Галахад
 
гуру
18.02.21
11:26
(20) Запросом быстрее.
22 Волшебник
 
18.02.21
11:34
(21) Это паразитная нагрузка на сервер. Эту тупую работу может выполнить клиентский компьютер.
При большой загруженности сервера он может уйти в себя.
23 Hans
 
18.02.21
11:39
(0) Не вижу говнокода.
24 Волшебник
 
18.02.21
11:40
(23) В запросе нет выборки из базы
25 Галахад
 
гуру
18.02.21
11:41
(22) Ну а если код и так выполняется на сервере. Например регламентное задание.
26 Волшебник
 
18.02.21
11:42
(25) Есть сервер 1С и сервер СУБД, два разных сервера
27 Serg_1960
 
18.02.21
12:35
Эээ... чисто от скуки и спортивного интереса ради :)
Я могу быстренько набросать лаконичный (с десяток строк) универсальный алгоритм для объединения разнородных таблиц (с различными составом колонок).  Но только если кто-то потом согласится его протестировать на скорость на больших объёмах с другими алгоритмами (например, с запросом как у автора). Интересно же проверить идею :)
28 Галахад
 
гуру
18.02.21
13:17
(27) Да легко. Самому интересно.
29 Fragster
 
гуру
18.02.21
13:34
(28) сортируешь обе таблицы по ключам сопоставления, далее в один проход делаешь третью таблицу
30 Малыш Джон
 
18.02.21
13:42
(29) а если исходный порядок надо сохранить? предварительно добавлять поле для сохранения порядка?
31 Малыш Джон
 
18.02.21
13:47
(27) алгоритм, я думаю, тут все смогут придумать. Проблемы две: 1) каким бы наглядным(не синоним слову "лаконичный") он не был, все равно тому, кто будет после тебя, нужно будет некоторое время, чтобы сообразить, что ты такое сделал (а запрос понимается сходу) и б) он будет медленнее варианта с запросом, особенно на больших объемах.
У варианта с запросом, естественно, свои недостатки
32 fisher
 
18.02.21
14:04
(0) Ну, такое... Лично на меня такой код действует как лимон, ибо по ресурсам очевидный оверкил. Есть варианты когда такой подход допустим и когда не очень. Я так никогда не делаю, ибо первые случаи имеют тенденцию плавно и незаметно перетекать во вторые плюс чувство прекрасного не позволяет.
Многие считают иначе. В основном те, кто избалован высокоуровневым API и у кого баланс между простотой кода и эффективностью сильно смещен в первое.
33 H A D G E H O G s
 
18.02.21
14:09
(30) Делаешь копии таблиц
34 VladZ
 
18.02.21
14:14
(0) Моё мнение: можно использовать в определенных ситуациях.

У меня такой вопрос: почему при получении первой части данных (первая таблица) мы не могли сразу получить вторую часть запросом? В чем сложность?
35 vi0
 
18.02.21
14:17
(6) встречный вопрос - запрос в цикле имеет право на жизнь?
36 Вафель
 
18.02.21
14:23
тут нужен мердж
самому такое писать влом ибо нужно быть очень аккуратным
37 Garykom
 
гуру
18.02.21
14:24
(35) иногда это быстрее
например если распараллелить цикл по 50 фоновым на 20+ ядерном серваке
38 vi0
 
18.02.21
14:27
(37) ну вот и ответ на вопрос (0)
39 H A D G E H O G s
 
18.02.21
14:40
Запросом 44 милисекунды
Кодом 303
Таблица1=Новый ТаблицаЗначений;
    Таблица1.Колонки.Добавить("КолонкаСвязи",Новый ОписаниеТипов("Число",,,Новый КвалификаторыЧисла(15,0)));
    Таблица2=Таблица1.СкопироватьКолонки();
    ГенераторСЧ=Новый ГенераторСлучайныхЧисел();
    Для Счетчик=1 По 10000 Цикл
        НоваяСтрока=Таблица1.Добавить();
        НоваяСтрока.КолонкаСвязи=ГенераторСЧ.СлучайноеЧисло(0,50000);
        НоваяСтрока=Таблица2.Добавить();
        НоваяСтрока.КолонкаСвязи=ГенераторСЧ.СлучайноеЧисло(0,50000);
    КонецЦикла;
    
    Запрос=Новый Запрос;
    Запрос.Текст=
    "ВЫБРАТЬ
    |    Таблица1.КолонкаСвязи КАК КолонкаСвязи
    |ПОМЕСТИТЬ Таблица1
    |ИЗ
    |    &Таблица1 КАК Таблица1
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    Таблица2.КолонкаСвязи КАК КолонкаСвязи
    |ПОМЕСТИТЬ Таблица2
    |ИЗ
    |    &Таблица2 КАК Таблица2
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    Таблица1.КолонкаСвязи КАК КолонкаСвязи,
    |    Таблица2.КолонкаСвязи КАК КолонкаСвязиТаблицы2
    |ИЗ
    |    Таблица1 КАК Таблица1
    |        ЛЕВОЕ СОЕДИНЕНИЕ Таблица2 КАК Таблица2
    |        ПО Таблица1.КолонкаСвязи = Таблица2.КолонкаСвязи";
    
    Запрос.УстановитьПараметр("Таблица1",Таблица1);
    Запрос.УстановитьПараметр("Таблица2",Таблица2);
    ВремяНачала=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Результат=Запрос.Выполнить().Выгрузить();
    ВремяОкночания=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Сообщить("Запросом "+Строка(ВремяОкночания-ВремяНачала));
    
    ВремяНачала=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Таблица1.Сортировать("КолонкаСвязи");
    Таблица1.Колонки.Добавить("КолонкаСвязиТаблицы2");
    Таблица2.Сортировать("КолонкаСвязи");
    ИндексТаблицы1=0;
    ИндексТаблицы2=0;
    Пока Истина Цикл
        СтрокаТаблицы1=Таблица1[ИндексТаблицы1];
        СтрокаТаблицы2=Таблица2[ИндексТаблицы2];
        Если СтрокаТаблицы1.КолонкаСвязи>=СтрокаТаблицы2.КолонкаСвязи Тогда
            ИндексТаблицы2=ИндексТаблицы2+1;
            Если СтрокаТаблицы1.КолонкаСвязи=СтрокаТаблицы2.КолонкаСвязи Тогда
                СтрокаТаблицы1.КолонкаСвязиТаблицы2=СтрокаТаблицы2.КолонкаСвязи;
            КонецЕсли;
        Иначе
            ИндексТаблицы1=ИндексТаблицы1+1;
        КонецЕсли;
        Если ИндексТаблицы1>= Таблица1.Количество() Тогда
            Прервать;
        КонецЕсли;
        Если ИндексТаблицы2>= Таблица2.Количество() Тогда
            Прервать;
        КонецЕсли;        
    КонецЦикла;
    ВремяОкночания=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Сообщить("Кодом "+Строка(ВремяОкночания-ВремяНачала));
40 H A D G E H O G s
 
18.02.21
14:41
Плата за плохую математику 1С. В Дельфи было бы быстрее кодом.
41 lEvGl
 
гуру
18.02.21
14:41
в общем случае запросом быстрее и удобнее писать, при написании обходов циклами как раз и получается говнокод, даже визуально пока а б ц цикл н + 1 и остальные Стр и подобное. быстродействие будет зависеть от контекста выполнения, запрос всегда на субд, код на клиенте или сервере приложения, что мощнее по железу, то и будет быстрее. все от конкретной ситуации загруженности железа зависит.
поддержу (23)
42 lEvGl
 
гуру
18.02.21
14:42
(34) ну это прозрачный пример, я так понимаю
43 H A D G E H O G s
 
18.02.21
14:43
Потери размазаны по операциям сравнения, получению строки по индексу, и, удивительно, на сортировку.
http://prntscr.com/zz17qo
44 lEvGl
 
гуру
18.02.21
14:44
(40) 1с это в принципе производная от более низкоуровневых языков
45 H A D G E H O G s
 
18.02.21
14:44
Ну и СУБД у меня не нагружена и tempdb на SSD (а скорее, в памяти).
46 lEvGl
 
гуру
18.02.21
14:46
(45) в этом конкретика ситуации и есть
те, кто топит за разгрузку субд видимо сталкивались с проблемами в этой части. они есть у всех, но тут сталкивались видимо особенно остро
47 H A D G E H O G s
 
18.02.21
14:46
Забавно, но SQL соединил через hashmatch
48 Garykom
 
гуру
18.02.21
14:48
(39) У тебя "кодом" говно какое то
49 H A D G E H O G s
 
18.02.21
14:48
А причина, кстати, в том, что теперь 1С вставляет ТЗ в ВТ через bulk insert, а раньше просто через Insert
50 H A D G E H O G s
 
18.02.21
14:49
Жить стало лучше, жить стало веселее, а твое знания внезапно устарели, а чем 1С даже не уведомила.
51 H A D G E H O G s
 
18.02.21
14:49
Так что код автора теперь имеет право на жись.
И, пожалуй, я связывать ТЗ теперь буду на сервере
52 Garykom
 
гуру
18.02.21
14:50
(48)+ Сделай плиз просто как в (20)
Все записи из двух ТЗ в одну новую ТЗ из 3-х колонок Справочник1, КоличествоА, КоличествоБ
Пиши 0 где нет значения а затем Свернуть
53 H A D G E H O G s
 
18.02.21
14:50
(51) на сервере СУБД
54 H A D G E H O G s
 
18.02.21
14:50
(52) Держи, там немного
https://yadi.sk/d/5gcAqwEYTrvsig
55 ИС-2
 
naïve
18.02.21
14:53
(10) наоборот, в если помещаем таблицы в запрос, то получается медленее. Делал специально опыты несколько лет назад
56 lEvGl
 
гуру
18.02.21
14:55
(39) вот вот, про такие коды я и говорю, индекс шминдекс + 1 ><= и остальные знаки "препинания"
Пока Истина Цикл
        СтрокаТаблицы1=Таблица1[ИндексТаблицы1];
        СтрокаТаблицы2=Таблица2[ИндексТаблицы2];
        Если СтрокаТаблицы1.КолонкаСвязи>=СтрокаТаблицы2.КолонкаСвязи Тогда
            ИндексТаблицы2=ИндексТаблицы2+1;

и это пишет человек, который имеет опыт, интересуется производительностью и технической частью, а если это студент или кому пофигу на все это, то решение этой же задачи в коде будет иметь такой унылый вид, что всегда проще написать самому заново
57 H A D G E H O G s
 
18.02.21
14:56
(56) Это типовой mergejoin, типовее нет, какие вопросы то?
58 lEvGl
 
гуру
18.02.21
15:01
(57) джоин кодовый, такой кодовый.. вопросы к читабельности и проблемности разбора этих "логик", которые там творятся, в (0) типовой запрос через вт и прозрачность на высоте и количество текста минимум (это про запрос. там даже создание ТЗ кодом занимает места больше чем, сам запрос)
59 lEvGl
 
гуру
18.02.21
15:02
(57) ну я к тому что кодом лучше и не получится, если только не озадачиться именно этим
60 fisher
 
18.02.21
15:12
(43) Ты протестил наихудший случай, которых на практике фактически не будет (поэтому у тебя почти 20000 итераций при 10000 строк в таблицах).
Во-вторых, почему ты не включил в замер времени выполнения запроса передачу таблиц на сервер? Плюс это время будет расти при увеличении размеров строк таблиц.
(51) Даже при наличии выигрыша по скорости, для реально больших таблиц (не только по количеству строк, но и по размеру строки) будут расти и накладные расходы на сервере СУБД, ухудшая его интегральную производительность.
61 fisher
 
18.02.21
15:18
Ну и плюс утилизация сетки, если по серверам разнесено.
62 Малыш Джон
 
18.02.21
15:18
(60)
1) Почему наихудший? Случайным образом заполненные таблицы. Почему такого на практике не будет?
2) ну вон же присланы данные замера производительности. По сравнению с временем выполнения запроса - затраты на передачу таблиц нулевые
3) понятно, что будут расти нагрузка на сервер. Вопрос на сколько: На 10 - 20 - 50% или на 0.00001%?
63 lEvGl
 
гуру
18.02.21
15:19
(60)при реально больших таблицах ресурсы будут расти и на сервере приложений, не говоря о клиенте
64 fisher
 
18.02.21
15:24
(62)
1) в реальности ты вряд ли будешь джойнить таблицы, в которых ни одного ключа не совпадает
2) я бы все-таки передвинул инициализацию времени начала замера действительно в самое начало, чтобы исключить возможные косяки замера производительности
65 Почему 1С
 
18.02.21
15:30
(39) Почему в Если СтрокаТаблицы1.КолонкаСвязи>=СтрокаТаблицы2.КолонкаСвязи Тогда
не двигается индекс таблицы 1 при равенстве ключей?
66 fisher
 
18.02.21
15:33
(62)
3) в том-то и дело, что это проблематично спрогнозировать, если начать применять такой подход повсеместно.
67 Почему 1С
 
18.02.21
15:33
(0) Не знаю говнокод или нет, но такой поход использую не только для соединения таблиц, но и построения итогов (иерархий) по таблицам.
68 Serg_1960
 
18.02.21
15:35
(28) Ой, sorry. Я вышел с ветки и отвлёкся работой :)
Обещанный смешной (но рабочий) алгоритм:

    // заполнение таблиц для примера
    
    Т1 = Новый ТаблицаЗначений;
    Т1.Колонки.Добавить("а", Новый ОписаниеТипов("Булево"));
    Т1.Колонки.Добавить("б", Новый ОписаниеТипов("Число"));
    
    НовСтр = Т1.Добавить();
    НовСтр.а = Истина;
    НовСтр.б = 1;
    НовСтр = Т1.Добавить();
    НовСтр.а = Ложь;
    НовСтр.б = 2;
    
    
    Т2 = Новый ТаблицаЗначений;
    Т2.Колонки.Добавить("а", Новый ОписаниеТипов("Булево"));
    Т2.Колонки.Добавить("г", Новый ОписаниеТипов("Число"));
    
    НовСтр = Т2.Добавить();
    НовСтр.а = Истина;
    НовСтр.г = 3;
    НовСтр = Т2.Добавить();
    НовСтр.а = Ложь;
    НовСтр.г = 4;
    
    // Собственно говоря сам алгоритм "объединения" таблиц
    
    Т3 = ?(Т1.Количество() > Т2.Количество(), Т1.Скопировать(), Т2.Скопировать());
    Тх = ?(Т1.Количество() > Т2.Количество(), Т2.Скопировать(), Т1.Скопировать());
    Для к = 1 По Тх.Количество() Цикл Т3.Вставить(0); КонецЦикла;
    
    Для к = 0 По Тх.Колонки.Количество()-1 Цикл
        Имя = Тх.Колонки[к].Имя;
        Если Т3.Колонки.Найти(Имя) = Неопределено Тогда
            Т3.Колонки.Добавить(Имя, Тх.Колонки[к].ТипЗначения);
        КонецЕсли;
        Т3.ЗагрузитьКолонку(Тх.ВыгрузитьКолонку(Имя),Имя);
    КонецЦикла;
    
    // чисто для примера работа с "объединенной" таблицей
    
    Т3.Свернуть("а","б,г");
    Т3.ВыбратьСтроку();
69 Вафель
 
18.02.21
16:00
сдается мне что в коде основная проблема это сортировка таблиц
70 Garykom
 
гуру
18.02.21
16:00
(54)
Запросом 157
Кодом 347

"связывать ТЗ теперь буду на сервере СУБД" +1
71 Garykom
 
гуру
18.02.21
16:02
(70)+ Точнее так

Кодом 631
Запросом 157
Моим кодом 357



&НаСервереБезКонтекста
Процедура ТестированиеНаСервере()
    Таблица1=Новый ТаблицаЗначений;
    Таблица1.Колонки.Добавить("КолонкаСвязи",Новый ОписаниеТипов("Число",,,Новый КвалификаторыЧисла(15,0)));
    Таблица1.Колонки.Добавить("КолонкаЗначения",Новый ОписаниеТипов("Число",,,Новый КвалификаторыЧисла(15,0)));
    Таблица2=Таблица1.СкопироватьКолонки();
    ГенераторСЧ=Новый ГенераторСлучайныхЧисел();
    Для Счетчик=1 По 10000 Цикл
        НоваяСтрока=Таблица1.Добавить();
        НоваяСтрока.КолонкаСвязи=ГенераторСЧ.СлучайноеЧисло(0,50000);
        НоваяСтрока.КолонкаЗначения=ГенераторСЧ.СлучайноеЧисло(0,500);
        НоваяСтрока=Таблица2.Добавить();
        НоваяСтрока.КолонкаСвязи=ГенераторСЧ.СлучайноеЧисло(0,50000);
        НоваяСтрока.КолонкаЗначения=ГенераторСЧ.СлучайноеЧисло(0,500);
    КонецЦикла;
    
    ВремяНачала=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Запрос=Новый Запрос;
    Запрос.Текст=
    "ВЫБРАТЬ
    |    Таблица1.КолонкаСвязи КАК КолонкаСвязи,
    |    Таблица1.КолонкаЗначения КАК КолонкаЗначения
    |ПОМЕСТИТЬ Таблица1
    |ИЗ
    |    &Таблица1 КАК Таблица1
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    Таблица2.КолонкаСвязи КАК КолонкаСвязи,
    |    Таблица2.КолонкаЗначения КАК КолонкаЗначения
    |ПОМЕСТИТЬ Таблица2
    |ИЗ
    |    &Таблица2 КАК Таблица2
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    Таблица1.КолонкаСвязи КАК КолонкаСвязи,
    |    Таблица1.КолонкаЗначения КАК КолонкаЗначения1,
    |    Таблица2.КолонкаЗначения КАК КолонкаЗначения2
    |ИЗ
    |    Таблица1 КАК Таблица1
    |        ЛЕВОЕ СОЕДИНЕНИЕ Таблица2 КАК Таблица2
    |        ПО Таблица1.КолонкаСвязи = Таблица2.КолонкаСвязи";
    
    Запрос.УстановитьПараметр("Таблица1",Таблица1);
    Запрос.УстановитьПараметр("Таблица2",Таблица2);
    //ВремяНачала=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Результат=Запрос.Выполнить().Выгрузить();
    ВремяОкночания=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Сообщить("Запросом "+Строка(ВремяОкночания-ВремяНачала));
    
    ВремяНачала=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Таблица1.Сортировать("КолонкаСвязи");
    Таблица1.Колонки.Добавить("КолонкаСвязиТаблицы2");
    Таблица2.Сортировать("КолонкаСвязи");
    ИндексТаблицы1=0;
    ИндексТаблицы2=0;
    Пока Истина Цикл
        СтрокаТаблицы1=Таблица1[ИндексТаблицы1];
        СтрокаТаблицы2=Таблица2[ИндексТаблицы2];
        Если СтрокаТаблицы1.КолонкаСвязи>=СтрокаТаблицы2.КолонкаСвязи Тогда
            ИндексТаблицы2=ИндексТаблицы2+1;
            Если СтрокаТаблицы1.КолонкаСвязи=СтрокаТаблицы2.КолонкаСвязи Тогда
                СтрокаТаблицы1.КолонкаСвязиТаблицы2=СтрокаТаблицы2.КолонкаСвязи;
            КонецЕсли;
        Иначе
            ИндексТаблицы1=ИндексТаблицы1+1;
        КонецЕсли;
        Если ИндексТаблицы1>= Таблица1.Количество() Тогда
            Прервать;
        КонецЕсли;
        Если ИндексТаблицы2>= Таблица2.Количество() Тогда
            Прервать;
        КонецЕсли;        
    КонецЦикла;
    ВремяОкночания=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Сообщить("Кодом "+Строка(ВремяОкночания-ВремяНачала));
    
    
    // Моим кодом
    ВремяНачала=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Таблица3=Новый ТаблицаЗначений;
    Таблица3.Колонки.Добавить("КолонкаСвязи",Новый ОписаниеТипов("Число",,,Новый КвалификаторыЧисла(15,0)));
    Таблица3.Колонки.Добавить("КолонкаЗначения1",Новый ОписаниеТипов("Число",,,Новый КвалификаторыЧисла(15,0)));
    Таблица3.Колонки.Добавить("КолонкаЗначения2",Новый ОписаниеТипов("Число",,,Новый КвалификаторыЧисла(15,0)));
    
    Для Каждого ТекСтр Из Таблица1 Цикл
        НовСтр = Таблица3.Добавить();
        НовСтр.КолонкаСвязи = ТекСтр.КолонкаСвязи;
        НовСтр.КолонкаЗначения1 = ТекСтр.КолонкаЗначения;
        НовСтр.КолонкаЗначения2 = 0;
    КонецЦикла;
    
    Для Каждого ТекСтр Из Таблица2 Цикл
        НовСтр = Таблица3.Добавить();
        НовСтр.КолонкаСвязи = ТекСтр.КолонкаСвязи;
        НовСтр.КолонкаЗначения1 = 0;
        НовСтр.КолонкаЗначения2 = ТекСтр.КолонкаЗначения;
    КонецЦикла;
    
    Таблица3.Свернуть("КолонкаСвязи", "КолонкаЗначения1, КолонкаЗначения2");
    
    ВремяОкночания=ТекущаяУниверсальнаяДатаВМиллисекундах();
    Сообщить("Моим кодом "+Строка(ВремяОкночания-ВремяНачала));
    
КонецПроцедуры

&НаКлиенте
Процедура Тестирование(Команда)
    ТестированиеНаСервере();
КонецПроцедуры

72 H A D G E H O G s
 
18.02.21
16:05
(64) Ключи совпадают и довольно часто.
73 Малыш Джон
 
18.02.21
16:05
(71) и теперь ещё сравнить результат-то один и тот же получился или нет))
74 Малыш Джон
 
18.02.21
16:07
(71) кстати, для объединения можно использовать таблицу1, просто туда вставить нужное количество пустых строк, а потом поколоночно загрузить таблицу2. Получиться быстрее должно.
75 H A D G E H O G s
 
18.02.21
16:07
(60) Ты реально думаешь, что ТЗ уходит на сервер в точке
УстановитьПараметр()
?
А не при Запрос.Выполнить()
?
76 H A D G E H O G s
 
18.02.21
16:07
(74) Это не соединение по ключу
77 Garykom
 
гуру
18.02.21
16:08
(75) Уходит да но полное время же хотим, время установки параметра + время передачи установленного на сервер
78 H A D G E H O G s
 
18.02.21
16:09
(71) Что будет, если будут строковые ресурсы или ссылочные?
79 Малыш Джон
 
18.02.21
16:09
(76) так и в (71) (в третьем варианте) тоже не соединение
80 Garykom
 
гуру
18.02.21
16:10
(78) будет другой алгоритм
81 Garykom
 
гуру
18.02.21
16:12
(80)+ Вместо Свернуть, будет Сортировать и цикл сравнивающий пары строк, перенося в новую ТЗ
82 Малыш Джон
 
18.02.21
16:13
(78)
   - Товарищ Сталин, дошла информация, что маршал Рокоссовский, не состоя в браке с актрисой Серовой, открыто с ней сожительствует и всячески разлагается. Что делать будем?
   - Чьто будэм, чьто будэм... Завыдоват будэм!
83 H A D G E H O G s
 
18.02.21
16:16
Запросом 157 у Гарри
Запросом 40 у Hadgehogs

Это все, что нужно знать о оборудовании Гарри на древних ксеонах.
84 H A D G E H O G s
 
18.02.21
16:16
Вот что страшно
85 H A D G E H O G s
 
18.02.21
16:17
Потом подключаешься к клиентам и теряешь драгоценные мгновения бесценной жизни, смотря на крутящееся колесико в ERP на 2.2 Ггц.
86 Малыш Джон
 
18.02.21
16:18
(85) Человеку, не желающему терять драгоценные мгновения бесценной жизни, в принципе не рекомендуется связываться с ERP. На любом оборудовании.
87 Garykom
 
гуру
18.02.21
16:20
(83) Это рабочий сервак на который я маты складываю
https://i.paste.pics/23acaba9bb778a9c5cc74f42b7abd7a5.png?trs=60174cc3ec6c8948da637408dbbd4706e227433d9d28e072a7bc087834a70180

Сча тестану на паре зионов
88 fisher
 
18.02.21
16:21
Все равно не брошу работать с ТЗ "по месту" :)=
Вот еще, себе "руку сбивать" из-за тормозов интерпретатора, да еще сиквел обижать.
89 Малыш Джон
 
18.02.21
16:23
Если надо смержить данных
Все равно на серв не брошу
Буду мержить их руками
Потому что я хороший
90 H A D G E H O G s
 
18.02.21
16:24
(87) мммм., Silver, миленько.
91 Garykom
 
гуру
18.02.21
16:24
(90) Виртуалка в облаке
92 H A D G E H O G s
 
18.02.21
16:25
(91) Но ведь Silver, да?
А это твое облако или стороннее?
93 Шоколадный глаз
 
18.02.21
16:27
(0) Любой код имеет право на жизнь, главное не показывай его заказчику.
94 Garykom
 
гуру
18.02.21
16:28
(92) Чужое, Сотел

кста на моем рабочем инженернике i7-6400T
Запросом 127
Кодом 198
Моим кодом 114
95 Garykom
 
гуру
18.02.21
16:29
(94) sql - Postgres
96 Megas
 
18.02.21
16:31
(4)
Особенно в одноразовой обработке.
Потому что буквально через пару недель на рабочем столе лежит 12штук ВнешняяОбработка1 - 12,  с кнопокой "выполнить"
97 Garykom
 
гуру
18.02.21
16:31
(94)+ На разогнанном 1650v2
Запросом 173
Кодом 168
Моим кодом 111
98 Garykom
 
гуру
18.02.21
16:32
(97)+ Но это файловая, серверной там у меня не стоит
99 H A D G E H O G s
 
18.02.21
16:39
(97) SQL - MSSQL, i5-8600k, 40 мсек.
100 Garykom
 
гуру
18.02.21
16:40
(99) ты мой код запусти
101 Garykom
 
гуру
18.02.21
16:40
(100) и скажи скоко
102 Serg_1960
 
18.02.21
16:47
Эээ... народ, мне тут кто-то обещали мой код проверить :(
103 H A D G E H O G s
 
18.02.21
16:50
Кодом 302
Моим кодом 169
Запросом 59
104 Serg_1960
 
18.02.21
16:56
(103) Это для кода, указанного в (39)?
105 Garykom
 
гуру
18.02.21
16:56
(103) интересно в сравнении:

i5-8600k, sql, mssql
Кодом 302
Моим кодом 169
Запросом 59

1650v2, sql, postgres
Запросом 173
Кодом 168
Моим кодом 111

i7-6400T, файловая
Запросом 127
Кодом 198
Моим кодом 114
106 Garykom
 
гуру
18.02.21
16:57
(105) тьфу перепутал
1650v2, файловая
Запросом 173
Кодом 168
Моим кодом 111

i7-6400T, серверная, postgres
Запросом 127
Кодом 198
Моим кодом 114
107 Garykom
 
гуру
18.02.21
16:59
Короче хрень какая то в итоге.

Если база файловая то лучше кодом.
Если база серверная на mssql (или заточенном postgres) то запросом.
Если серверная на не заточенном дефолтном postgres - хз как лучше, тестить надо
108 H A D G E H O G s
 
18.02.21
17:01
(105) А версия платформы?
109 Serg_1960
 
18.02.21
17:05
+(104) Всё страньше и страньше! Всё чудесатее и чудесатее!

Проверил мой алгоритм и алгоритмы из (39) на клиенте:
Мой код 94

Запросом(39) 422
Кодом(39) 906
110 H A D G E H O G s
 
18.02.21
17:06
(109) Толстый клиент щтоле?
111 Serg_1960
 
18.02.21
17:07
(110) Угу. У меня же УПП :)
112 H A D G E H O G s
 
18.02.21
17:08
(111) Ну так это толстый клиент, он мертв уже.
113 Serg_1960
 
18.02.21
17:10
Пойду скажу юзверям, а то они не в курсе :)
114 Garykom
 
гуру
18.02.21
17:11
(108) 8.3.18.1208
115 H A D G E H O G s
 
18.02.21
18:47
Написал merg на Дельфи, быстрее чем 1С где то в 100 раз.
31 мсек на 100000 (не 10000) записей.

type
  УказательНаЗапись = ^ТипЗапись;

  ТипЗапись = record
    КолонкаСвязи: integer;
    КолонкаСвязиТаблицы2: integer;
  end;

implementation

{$R *.dfm}

function ФункцияСравнения(Объект1: Pointer; Объект2: Pointer): integer;
begin
  if УказательНаЗапись(Объект1)^.КолонкаСвязи > УказательНаЗапись(Объект2)^.КолонкаСвязи
  then
    Result := 1
  else if УказательНаЗапись(Объект1)^.КолонкаСвязи = УказательНаЗапись(Объект2)
    ^.КолонкаСвязи then
    Result := 0
  else
    Result := -1;
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  Таблица1, Таблица2: TList;
  СтрокаТаблицы, СтрокаТаблицы1, СтрокаТаблицы2: УказательНаЗапись;
  ИндексТаблицы1, ИндексТаблицы2, Счетчик, ВремяНачала, ВремяОкончания: integer;
begin
  Таблица1 := TList.Create;
  Таблица2 := TList.Create;
  for Счетчик := 1 to 100000 do
  begin
    GetMem(СтрокаТаблицы, SizeOf(ТипЗапись));
    ZeroMemory(СтрокаТаблицы, SizeOf(ТипЗапись));
    СтрокаТаблицы^.КолонкаСвязи := Random(50000);
    Таблица1.Add(СтрокаТаблицы);

    GetMem(СтрокаТаблицы, SizeOf(ТипЗапись));
    ZeroMemory(СтрокаТаблицы, SizeOf(ТипЗапись));
    СтрокаТаблицы^.КолонкаСвязи := Random(50000);
    Таблица2.Add(СтрокаТаблицы);
  end;

  ВремяНачала := GetTickCount;

  Таблица1.Sort(ФункцияСравнения);
  Таблица2.Sort(ФункцияСравнения);
  ИндексТаблицы1 := 0;
  ИндексТаблицы2 := 0;
  while True do
  begin
    СтрокаТаблицы1 := Таблица1.Items[ИндексТаблицы1];
    СтрокаТаблицы2 := Таблица2.Items[ИндексТаблицы2];
    if True then
      if СтрокаТаблицы1^.КолонкаСвязи >= СтрокаТаблицы2^.КолонкаСвязи then
      Begin
        ИндексТаблицы2 := ИндексТаблицы2 + 1;
        if СтрокаТаблицы1^.КолонкаСвязи = СтрокаТаблицы2^.КолонкаСвязи then
          СтрокаТаблицы1^.КолонкаСвязиТаблицы2 := СтрокаТаблицы2^.КолонкаСвязи;
      End
      else
        ИндексТаблицы1 := ИндексТаблицы1 + 1;
    if ИндексТаблицы1 >= Таблица1.Count then
      break;
    if ИндексТаблицы2 >= Таблица2.Count then
      break;
  end;
  ВремяОкончания := GetTickCount;

  Memo1.Lines.BeginUpdate;
  Memo1.Lines.Clear;
  Memo1.Lines.Add('Время выполнения: ' + IntToStr(ВремяОкончания - ВремяНачала));
  Memo1.Lines.Add('КолонкаСвязи     КолонкаСвязиТаблицы2');
  for Счетчик := 1 to 100000 do
  begin
    СтрокаТаблицы := Таблица1.Items[Счетчик - 1];
    Memo1.Lines.Add(IntToStr(СтрокаТаблицы^.КолонкаСвязи)+'   '+IntToStr(СтрокаТаблицы^.КолонкаСвязиТаблицы2));
    FreeMem(СтрокаТаблицы);
    СтрокаТаблицы := Таблица2.Items[Счетчик - 1];
    FreeMem(СтрокаТаблицы);
  end;
  Memo1.Lines.EndUpdate;

end;
116 Fragster
 
гуру
18.02.21
18:56
(112) не надо вот этого. торстый клиент с управляемыми формами вполне себе жив
117 Garykom
 
гуру
18.02.21
20:05
(115) а терь добавь проверку лицензионности в цикле (как сча в 1С) и будет упс
118 H A D G E H O G s
 
18.02.21
20:20
(117) Откуда дрова?
Собрал события LIC - ничего криминального.
119 Garykom
 
гуру
18.02.21
20:36
(118) ключик выдерни во время длинного цикла ))
120 H A D G E H O G s
 
18.02.21
20:55
(119) У меня проглицензии
121 Bigbro
 
19.02.21
04:15
я конечно совсем не эксперт но реально разница ведь есть только при больших таблицах.
таблицы изначально на клиенте.
и если это не критически важная по времени операция смысла грузить ей сеть, сервер приложений, сервер бд - нет никакого. пусть клиент пыхтит себе тихонечко не мешая всем остальным работать. даже если это займет в 4 раза больше времени - нулевая нагрузка на общие ресурсы это оправдывает. я так это вижу.
122 Галахад
 
гуру
19.02.21
04:55
Хм. Похоже не все так однозначно.
123 Почему 1С
 
19.02.21
06:33
(122) Что не однозначно то, читаемость кода в (0) на порядок выше изобретения велосипедов что были ниже, надежность кода тоже на порядок выше, уже этого достаточно чтобы сделать выводы в пользу такого подхода.
124 Галахад
 
гуру
19.02.21
06:43
(68) Обещанные тесты:

Алгоритм 1.

    Для каждого Стр Из Таблица1 Цикл
        НовСтр = Таблица2.Добавить();
        ЗаполнитьЗначенияСвойств(НовСтр, Стр);
    КонецЦикла;
    
    Таблица2.Свернуть("КолонкиГруппировок", "КолонкиСуммирования");

Алгоритм 2.

    Т3 = ?(Т1.Количество() > Т2.Количество(), Т1.Скопировать(), Т2.Скопировать());
    Тх = ?(Т1.Количество() > Т2.Количество(), Т2.Скопировать(), Т1.Скопировать());
    Для к = 1 По Тх.Количество() Цикл Т3.Вставить(0); КонецЦикла;
    
    Для к = 0 По Тх.Колонки.Количество()-1 Цикл
        Имя = Тх.Колонки[к].Имя;
        Если Т3.Колонки.Найти(Имя) = Неопределено Тогда
            Т3.Колонки.Добавить(Имя, Тх.Колонки[к].ТипЗначения);
        КонецЕсли;
        Т3.ЗагрузитьКолонку(Тх.ВыгрузитьКолонку(Имя),Имя);
    КонецЦикла;

    Таблица2.Свернуть("КолонкиГруппировок", "КолонкиСуммирования");

Количество строк в таблице 1
Количество строк в таблице 2
Время алгоритм 1
Время алгоритм 2

Для таблиц с двумя колонками:
200 000
200 000
3 313
4 132

200 000
150 000
2 738
2 689

200 000
100 000
2 544
1 705

100 000
100 000
1 252
1 202

Для таблиц с тремя колонками группировок и 10 суммирования
200 000
100 000
3 314
4 281

200 000
50 000
3 033
2 126

100 000
50 000
1 709
1 553

50 000
40 000
791
985

50 000
30 000
780
725

100 000
70 000
1 614
2 255

50 000
40 000
803
960

50 000
30 000
771
731
125 Галахад
 
гуру
19.02.21
07:05
(123) Ну если почитать ветку, сначала всё было однозначно, а потом мнения разделились.
126 Почему 1С
 
19.02.21
07:15
(125) Соревнования что выполняется быстрее, в (0) результат сразу очевиден, все знают как работает левое соединение, то в коде хитрых манипуляций с таблицами надо посидеть и поразбираться, а будут ли увеличено количество строк в таблице1 если в таблице2 ей будет соответствовать несколько ключей и так далее.
127 Волшебник
 
19.02.21
07:57
Извращенцы...
128 Garykom
 
гуру
19.02.21
09:46
(127) Это в 1С разрабы платформы извращенцы, настолько умудриться затормозить исполнение кода что быстрей стало ТЗ на сервер SQL отправить и там соединить
129 vi0
 
19.02.21
09:51
(128) просто разрабы ms sql профи в части оптимизации, это их экспертиза
130 fisher
 
19.02.21
10:11
(129) Да-да. "Это не у нас плохо - это у них хорошо". То что язык 1С в разы (а местами и на порядок) более тормозной, чем другие скриптовые языки - как бы не тайна.
131 Bigbro
 
19.02.21
10:12
в (124) нигде нет различия на порядок и даже в 2 раза... подобная разница не стоит затраченного на обсуждение времени.
132 fisher
 
19.02.21
10:15
Кстати вспомнил, что отладка 1С существенно замедляет выполнение при большом количестве итераций. Поэтому корректнее сравнивать без включения отладки и замера производительности.
133 Галахад
 
гуру
19.02.21
10:21
(131) Вроде именно эти методы и не обсуждали.
134 vi0
 
19.02.21
10:30
(130) я говорю, что тот факт что скл сервер быстрый - это не только в сравнении с 1с, а то что это именно его особенность
1с не позионируется как быстрая система
135 Конструктор1С
 
19.02.21
10:34
(4) обязательно и всегда. Нет ничего более постоянного, чем временное (с) К одноразовой обработке могут возвращаться снова и снова. И если у автора обработки ещё есть шанс расшифровать свой говнокод, то любой другой прогер будет обречен на муки
136 olegves
 
19.02.21
10:35
(121) я конечно извиняюсь, но где ты видел таблицы значений на тонком (или вэб) клиенте?
137 Garykom
 
гуру
19.02.21
10:40
(130) интересно если выяснится в итоге что платформа 1С специально заторможена... чтобы продавать "после корп" версию, которая "не тормозит" ))
138 fisher
 
19.02.21
11:13
(137) Да не. Прежде всего арифметика медленная и по понятным причинам. А остальные тормоза объясняются незаморачиванием на оптимизациях.
139 vi0
 
19.02.21
11:20
в 1с еще каждая строка кода дополняется какой то отладочной инфой
были обсуждения что код записанный в одну строку выполняется ненамного быстрее
140 Hans
 
24.02.21
16:55
(115) На Делфи уже по русски можно писать?