|
Можно ли оптимизировать такой код запроса | ☑ | ||
---|---|---|---|---|
0
espanol
23.12.13
✎
17:14
|
Соединяются две таблицы с разных пакетов, по средствам левого соединения, условие соединения:
СотрудникиИВендоры.Вендор = Итоговый.Номенклатура ИЛИ СотрудникиИВендоры.Вендор = Итоговый.Номенклатура.Родитель ИЛИ СотрудникиИВендоры.Вендор = Итоговый.Номенклатура.Родитель.Родитель ИЛИ СотрудникиИВендоры.Вендор = Итоговый.Номенклатура.Родитель.Родитель.Родитель ИЛИ СотрудникиИВендоры.Вендор = Итоговый.Номенклатура.Родитель.Родитель.Родитель.Родитель Т.к. если в запросе получаем поля, то нельзя использовать В ИЕРАРХИИ, вот приходится так делать... но из-за обращения через "." и из-за множества "ИЛИ" как я понимаю и запрос так медленно отрабатывается, там примерно по тысяч 10 записей и 10 тысячами соединяются. Минут 15 занимает примерно. Как можно сделать, так чтобы отрабатывало быстрее? |
|||
7
Avganec
23.12.13
✎
17:21
|
либо (3), либо пробовать сделать отдельно, в отдельном запросе, либо... вариантом много
|
|||
8
sapphire
23.12.13
✎
17:21
|
(3) А что даст такой РС?
|
|||
9
sapphire
23.12.13
✎
17:22
|
Вообще речь о том, что писари-адинеснеги вообще не думают, когда ваяют структуру метаданных.
Это же кому-то в голову пришло же подсунуть группу товара в какой-то справочник в виде поля "Вендор". Идиотизм. |
|||
10
Avganec
23.12.13
✎
17:24
|
(9) это не недумают, это просто не знают. либо мало опыта, либо действительно нет серого вещества
|
|||
11
MadHead
23.12.13
✎
17:25
|
(0) про то что это все плохо повторятся не хочу. Но думаю если поля с родителями выбрать в таблицу Итоговый и проиндексирвоать по этим полям будет быстрее.
|
|||
12
MadHead
23.12.13
✎
17:26
|
(0) СотрудникиИВендоры тоже добавить индексы по полям которые участвуют в условии соединения (если их нету)
|
|||
13
H A D G E H O G s
23.12.13
✎
17:28
|
(11)(12) Это ничего не изменит.
|
|||
14
MadHead
23.12.13
✎
17:30
|
(13) Почему же не изменит? Если соединение пойдет по индексированным полям, то очень даже изменит. Пусть автор попробует и напишет сюда результат
|
|||
15
YAGolova
23.12.13
✎
17:30
|
(9) А что в этом такого сверхполохого. У меня такое сплошь и рядом. И даже если честно более красивого решения придумать не могу. К примеру надо запретить определенному клиенту отгрузку товаров из определенной группы - как нормально организовать структуру. Очень итересно, честное слово буду пользоваться
|
|||
16
H A D G E H O G s
23.12.13
✎
17:31
|
НоменклатурныеГруппы помогут вам.
|
|||
17
H A D G E H O G s
23.12.13
✎
17:31
|
(14) Потому что главная проблема
Итоговый.Номенклатура.Родитель.Родитель.Родитель.Родитель |
|||
18
sapphire
23.12.13
✎
17:34
|
(14) От "В ИЕРЕАХИИ" не избавишься.
ИМХО, надо получить все возможные пары Номенклатура-Вендор |
|||
19
MadHead
23.12.13
✎
17:34
|
(17) главная проблема по этому всему провести соединение.
|
|||
20
selenat
23.12.13
✎
17:36
|
(19) ИЛИ в условии левого соединения - зло. А через тот же самый прием объединения и группиовки делается элементарно. А вот как лучше со всеми этими родителями поступить - эт подумать надо...
|
|||
21
MadHead
23.12.13
✎
17:36
|
(15) я подобную задачу оптимизировал следующим образом. При установке флага "запрета выборка" родителю, сразу флаг проставляется всем подчиненным. И возможность запрета можно определить по ближайшему родителю
|
|||
22
H A D G E H O G s
23.12.13
✎
17:38
|
(19) Нет.
Главная проблему 1С провести соединение Итоговый.Номенклатура.Родитель.Родитель.Родитель.Родитель 100500 раз |
|||
23
selenat
23.12.13
✎
17:39
|
Таки 4 временные таблицы с последовательным выделением в них родителей, а потом объединение запросов со всеми этими таблицами. И будет счастье.
|
|||
24
YAGolova
23.12.13
✎
17:40
|
(21) А при появлении очередного ближайшего родителя внутри головного родителя так же отслеживать и делать соответствующую запись? А где гарантия того, что пользователь набил эти флаги не на конкретные группы внутри группы и на появление новой группы этот флаг распространяться не должен?
|
|||
25
MadHead
23.12.13
✎
17:40
|
(18) я не спорю что мой вариант все равно остается кривым решением и не предусматривает (как и вариант автора) произвольной вложенности групп. но если в таблицу Итоговый добавить 4 поля с родителями разного уровня и по ним установить условие соединение будет на много лучше.
(22) вот по этому мы в таблице Итоговый получим 4 индексированных реквизита родитель1, родитель2, родитель3, родитель4 |
|||
26
H A D G E H O G s
23.12.13
✎
17:41
|
Пакетный запрос с менеджером ВТ
Получаем все различные вендоры - номенклатуры "Рекурсивно" строим в цикле (только сцуко правильно) - все различные родители по списку номенклатуры. Получаем таблицу значений Номенклатура Родители Засовываем в запрос. Делаем все на сервере 1С. Профит. |
|||
27
MadHead
23.12.13
✎
17:42
|
(24) это уже от логики зависит, если пользователь набил на конкретные группы то нужный флаг без всяких доп действий можно получить у ближайшего родителя
|
|||
28
selenat
23.12.13
✎
17:45
|
Даже с произвольной вложенностью иерархии сделать можно самым оптимальным способом.
|
|||
29
selenat
23.12.13
✎
17:51
|
Это как раз прекрасный пример запроса, где идеально работает техника замены левого соединения объединением и группировкой.
|
|||
30
bolobol
23.12.13
✎
17:53
|
(29) Вопрос стоит: "Как сделать?", а не какую технику использовать. Если объединяемую таблицу соберать более чем через одну точку - тот же результат будет.
|
|||
31
H A D G E H O G s
23.12.13
✎
17:54
|
(29) Не работает.
(30) Результат будет лучше, но все равно мрак. |
|||
32
selenat
23.12.13
✎
17:57
|
(31.1) отлично работает. Причем не просто отлично, а оптимально.
|
|||
33
selenat
23.12.13
✎
17:57
|
Не успею сейчас описать. Через минуту убегаю.
|
|||
34
bolobol
23.12.13
✎
17:57
|
(31) Понятно, что лучше - индексирование на вложенность через точку не работает, а значит в (0) уже теряем индексы, а в объединённой таблице уже и назначить индексы можно, если сами не подцепятся.
|
|||
35
bolobol
23.12.13
✎
18:00
|
Чёт вот не могу сообразить, как же собрать объединённую таблицу, неужели ж по максимальному уровню справочника Номенклатура переделывать количество временных таблиц???
|
|||
36
MadHead
23.12.13
✎
18:01
|
(35) а как еще? )))
|
|||
37
H A D G E H O G s
23.12.13
✎
18:01
|
(35) Думаю, да. Только не временных таблиц, а объединяемых запросов.
|
|||
38
H A D G E H O G s
23.12.13
✎
18:01
|
(36) Кодом собрать Номенклатура - Родители.
Это оптимум. |
|||
39
Fragster
гуру
23.12.13
✎
18:02
|
в группу и элемент иерархического справочника (или в отдельный регистр сведений) добавить реквизиты для групп: левое значение и правое значение, для элементов просто "значение", хранить там значения:
для иерархии (только группы, элементы только на нижнем уровне, в реальности немножко посложнее) а -б1 --б1в1 --б1в2 -б2 --б2в1 а: 1 и 15 б1: 2 и 9 б1в1: 3 и 5, у подчиненных элементов - 4 б1в2: 6 и 8, у подчиненных элементов - 7 б2: 10 и 14 б2в1: 11 и 13, у подчиненных элементов - 12 |
|||
40
Fragster
гуру
23.12.13
✎
18:02
|
в иерархии тогда превращается в "реквизит между левоезначение и правоезначение"
|
|||
41
H A D G E H O G s
23.12.13
✎
18:05
|
||||
42
Fragster
гуру
23.12.13
✎
18:08
|
||||
43
H A D G E H O G s
23.12.13
✎
18:09
|
(42) И что это даст?
|
|||
44
Fragster
гуру
23.12.13
✎
18:10
|
(42)+ немного оптимизированный из-за различия групп и элементов
|
|||
45
Fragster
гуру
23.12.13
✎
18:10
|
(43)->(40)
|
|||
46
bolobol
23.12.13
✎
18:10
|
(42) Это регулярная перестройка дерева. Причём - всего, целиком от места изменения до упора.
А построить его - всё равно, что перебрать все элементы, даже дороже. |
|||
47
Fragster
гуру
23.12.13
✎
18:10
|
минус - это при изменении вложенности групп надо много обновлять
|
|||
48
Fragster
гуру
23.12.13
✎
18:11
|
(46) как часто вы меняете именно структуру папок (при переносе элементов только одно значение меняется)
|
|||
49
Fragster
гуру
23.12.13
✎
18:12
|
да и вообще каково соотношение операций чтения/записи для справочника
|
|||
50
bolobol
23.12.13
✎
18:14
|
(48) Я - не менял ни разу, а вот пользователи... Да просто так иногда, пересунут чего-то куда-то.
Но если так индексировать с пробелами на вставку, а так же уровень подключить, то при перемещении только перемещаемую ветку переиндексировать, так сказать. Вроде и жизнеспособно, даже. Хм, Респект! |
|||
51
Fragster
гуру
23.12.13
✎
18:16
|
(50) были бы у 1с запросы на апдейты - то вынимание из структуры - 1 запрос, вставка в структуру - второй запрос и все. если немного подумать - то вообще одним запросом можно переносить
|
|||
52
Fragster
гуру
23.12.13
✎
18:19
|
еще есть Materialized Path, но он мне меньше нравится почему-то (ПолныйКод в терминах 1с)
|
|||
53
ILM
гуру
23.12.13
✎
18:25
|
Ответ уже дан в (26)
|
|||
54
RomanFire
23.12.13
✎
19:11
|
полностью ответ не дан
|
|||
55
sapphire
23.12.13
✎
19:14
|
Чего не хватает в (26)?
|
|||
56
Лефмихалыч
23.12.13
✎
19:20
|
(43) это даст between, сравнивающий целые числа вместо В ИЕРАРХИИ.
Лютая головоломка, но работает. |
|||
57
Fragster
гуру
23.12.13
✎
19:26
|
(56) на самом деле я не вполне понимаю, почему в платформу подобное не было встроено
|
|||
58
Лефмихалыч
23.12.13
✎
19:35
|
(57) платформоделы про это не в курсе. Тупо.
|
|||
59
Лефмихалыч
23.12.13
✎
19:37
|
ну или там на марше были соображения, что трудозатрахи СУБД на апдэйт границ при добавлении элементов внутрь иерархии будут больше, чем на запросы в цикле
там у них своя атмосфера какая-то |
|||
60
selenat
23.12.13
✎
19:44
|
Значит так. У меня дома пофигуратор не стоИт, поэтому рассказываю словами.
|
|||
61
Лефмихалыч
23.12.13
✎
19:49
|
(60) всё?..
|
|||
62
Fragster
гуру
23.12.13
✎
19:51
|
(61) а тебе мало?
|
|||
63
selenat
23.12.13
✎
19:54
|
Запрос не обязательно выполнять сразу весь, а можно выполнять кусочками, накапливая в менеджере временных таблиц все новые таблицы. А заодно выполняя отдельный кусочек проверять его результат. Что это дает? Вот есть у нас временная таблица номенклатуры. Строим таблицу ее родителей. Во первых кладем ее тоже во временную, во вторых можем тут же взять ее выборку и посмотреть, не пустая ли она. Если выборка не пустая, то можем построить таблицу родителей следующего уровня и проделать те же действия. И так до тех пор, пока не получим таблицу самых верхних родителей. Это легко можно сделать в цикле и получить во временных таблицах и саму номенклатуру, и родителей всех уровней. Дальше мы во вложенном запросе делаем объединение исходной таблицы с таблицей номенклатуры и со всеми таблицами родителей. Вводя служебные поля, группируя результат этого вложенного запроса и фильтруя результат группировки получаем ответ. Причем скорость метода будет практически такая же, как если бы родители не использовались. Просто если бы мы использовали только номенклатуру, без родителей, то было бы у нас в присоединяемой таблицы скажем 100 элементов. А с учетом родителей ну будет там скажем 150 элементов. Это как раз прелесть этого метода, когда мы заменяем левое соединение объединением и группировкой. Кто-нибудь что-нибудь понял из этого потока сознания? :)
|
|||
64
Лефмихалыч
23.12.13
✎
19:54
|
(62) ну, мне пока не понятно, в чем замес и я не могу понять - заинтригован я или нет
|
|||
65
Лефмихалыч
23.12.13
✎
19:56
|
(63) а если номенклатуры полтора миллиона записей?
|
|||
66
selenat
23.12.13
✎
19:59
|
(65) пофиг. Оптимальней не будет. Будет потрачено только то время, которое действительно необходимо. А вот левым запросом с да еще с конструкцией ИЛИ в соединении рискуешь получить повесившуюся систему.
|
|||
67
Лефмихалыч
23.12.13
✎
20:01
|
(66) сорри, я ни фуя не понял, но nested-set мне нравится больше :)
|
|||
68
ILM
гуру
23.12.13
✎
20:02
|
(63) Да ну нафиг, нужно сразу связку делать пар: ном и род_ном, сначала уровень 0, потом 1 и т.д., а далее как с деревьями.
|
|||
69
selenat
23.12.13
✎
20:04
|
Ладно. "Мое дело прокукарекать, а там хоть не рассветай" (С)
|
|||
70
selenat
23.12.13
✎
20:20
|
(68) ни с одним деревом работа не будет делаться быстрее, чем с линейным списком того же размера. В предлагаемом мной методе номенклатура со всеми родителями по сути выстраивается в линейный список.
|
|||
71
ILM
гуру
23.12.13
✎
20:31
|
(70) Прочитайте как деревья отражаются в таблицах, а особенно про индексы для деревьев.
|
|||
72
selenat
23.12.13
✎
20:41
|
(71) я пожалуй не поленился бы реализовать свой способ для этой задачи, чтобы сравнить его по скорости с тем, что предлагаете вы. :)
|
|||
73
Адимр
23.12.13
✎
20:48
|
(63) Я до конца не врубился.
То есть выполняем запрос к родителям в цикле пока результат запроса родителей не вернет пусто? В итоге что получам одну таблицу или две в каком виде? |
|||
74
Адимр
23.12.13
✎
20:49
|
или типа временные таблицы табНоменклатура, ТабРодители1, ТабРодители2 итп
|
|||
75
ILM
гуру
23.12.13
✎
20:53
|
Ну прочтите (26) и для полей Номенклатура, Родитель, Уровень создайте пакет.
|
|||
76
selenat
23.12.13
✎
20:53
|
(74) Да. И после этого как бы соединяем с объединением этих таблиц.
|
|||
77
Адимр
23.12.13
✎
21:05
|
(76) Какой вид итоговой таблицы предполагается? Две колонки? Как в (75) > (26)
|
|||
78
selenat
24.12.13
✎
06:40
|
(77) в условии задачи указано только условие для левого соединения. Для реализации этого условия в таблицах родителей сама номенклатура не нужна вообще.
|
|||
79
ViSo76
24.12.13
✎
08:13
|
Да оптимизация возможна с использованием временных таблиц. Работать будет быстро. Я такую конструкцию использую для быстрого поиска. Код набросаю чуть позже.
|
|||
80
ViSo76
24.12.13
✎
08:17
|
(63) Я практически такой метод использую. Так как количество иерархий конечное, у топикастра 4 временных таблицы которые затем объединяются
|
|||
81
espanol
24.12.13
✎
08:18
|
(11) в раз 10 стало работать быстрее, но с виду как-то ужасно выглядит =)
(37) надо будет через объедения попробовать... |
|||
82
mzelensky
24.12.13
✎
08:18
|
(0) Я полистал ветку, но так и не понял - зачем это все? Что хотят получить в конечном итоге?
|
|||
83
ViSo76
24.12.13
✎
08:25
|
И что в этом случае разве нельзя сделать так?
ПО Итоговый.Номенклатура В ИЕРАРХИИ( СотрудникиИВендоры.Вендор ) |
|||
84
ИС-2
naïve
24.12.13
✎
08:27
|
(0) Собрать всех Родителей во временной таблице т.е Родитель.Родитель как Родитель2. Если связь только по 1 полю, то вместо или использовать условие в.
(0) была у меня подобная тема. Тоже ругаюсь от такой структуры хранения, но ЭТО УДОБНО ПОЛЬЗОВАТЕЛЯМ. Во и приходится извращаться |
|||
85
Лефмихалыч
24.12.13
✎
08:31
|
(82) соединить по иерархии хотят
(83) ну попробуй |
|||
86
Klesk666
24.12.13
✎
08:50
|
Как вариант - создать реквизит и обновлять регламентным заданием
вот у меня тоже есть например в номенклатуре реквизит url который содержит путь который надо в браузере открывать под конкретную позицию, может быть прописана в родителе+артикул, может быть прописана в самом элементе, в запросах мне это не нужно, но можно сделать регламентное задание которое прописывает для элемента номенклатура конкретное значение, и использовать быстро в запросах. |
|||
87
espanol
24.12.13
✎
09:00
|
Через объединить, не катит, т.к. левое соединение, вот через внутреннее бы покатило, или если бы "ИЛИ" стояло в "ГДЕ", а не в условие соединения...
|
|||
88
selenat
24.12.13
✎
09:12
|
(87) "ничего то ты мишка не знаешь..." (с)
|
|||
89
selenat
24.12.13
✎
09:13
|
по ходу статью надо бы написать, дабы ссылку потом легко кидать было и не приходилось бы искать один-два важных поста по веткам обсуждения.
|
|||
90
selenat
24.12.13
✎
09:19
|
(87) смотри здесь посты 30 и 44
v8: Индексы в запросах. |
|||
91
ifso
24.12.13
✎
09:58
|
(2) +100500
Какая структура, такой и запрос. |
|||
92
k1us181b
24.12.13
✎
10:29
|
(91) вас смущает древовидная структура справочника?
|
|||
93
espanol
24.12.13
✎
10:32
|
(90) чето все равно какая-то офигня выходит ))
|
|||
94
selenat
24.12.13
✎
10:33
|
(93) "старайтесь лучше" (с)
|
|||
95
ifso
24.12.13
✎
10:44
|
(92) не сама структура, но ее использование
|
|||
96
Reaper_1c
24.12.13
✎
10:46
|
(92) Да за нее убивать надо.
|
|||
97
mistеr
24.12.13
✎
11:11
|
Да, транзитивное замыкание операция редкая, но иногда без нее никак. Могли бы встроить в платформу. Пусть не в запрос, но хотя бы как метод ДЗ.
Ко там постоянно тусуется на партнерских, озвучьте им при случае. |
|||
98
MadHead
24.12.13
✎
11:23
|
(81) я предложил быстрый в реализации способ ускорения. Если сделать "мега оптимальным способом" получите еще 10% ускорения. Я бы не замарачивался и рассмотрел возможность изменить архитектуру так что бы данный флаг можно было получать по ближайшему родителю или по родителю на определенном уровне. Или создал справочник "вендоры"
|
|||
99
Бледно Золотистый
24.12.13
✎
11:32
|
(97) Тут есть кстати статья неплохая по реализации транзитивного замыкания. Может понадобится кому.
http://infostart.ru/public/158512/ |
|||
100
badboychik
24.12.13
✎
11:53
|
а что мешает в коде найти всех родителей и поместить в массив, а потом его передать в запрос ?
|
|||
101
badboychik
24.12.13
✎
11:55
|
и написать
СотрудникиИВендоры.Вендор В (&НоменклатураИРодители) |
|||
102
badboychik
24.12.13
✎
11:58
|
Если "Итоговый.Номенклатура" это целый список, то да, selenat правильно говорит, что надо в цикле дописывать объединением родителей, а потом эту таблицу передавать дальше для соединения
|
|||
103
selenat
24.12.13
✎
12:02
|
(102) и мало того, все-таки довольно часто левое соединение само по себе строится 1Ской неоптимально. Посему я все-таки советую добиваться того же резудьтата, что дает левое соединение, при помощи объединения и группировки.
|
|||
104
MadHead
24.12.13
✎
12:07
|
(103) на счет левого соединения 1с строит не оптимально - это очень странно. Там же запрос практически 1 в 1 на СУБД уходит. тут вероятнее всего будет прирост от замена соединения объединением, но он будет не такой уж и высокий. Субъективно около 10%
|
|||
105
selenat
24.12.13
✎
12:16
|
(104) это у вас субъективно. Я не так хорошо знаю теорию, чтобы однозначно рассказать от каких именно факторов это зависит, но за годы применения этого приема могу из своих наблюдений сделать вывод, что в ряде случаев (не всегда конечно) на больших выборках время выполнения уменьшается на порядки. А был у меня случай, когда левое соединение вообще вешало систему, так что я через пару часов ожидания снимал сеанс 1С, а запрос с объединением и группировкой отрабатывал прекрасно за несколько минут.
|
|||
106
mistеr
24.12.13
✎
20:18
|
(99) О, спасибо. Есть где применить. Тоже думал, что кодом быстрее.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |