|
v7: Ускорить операции с ТЗ | ☑ | ||
---|---|---|---|---|
0
Злопчинский
03.12.11
✎
10:18
|
Прошу совета апологетов 1С++
. кучу времени в расчетах жрет конструкция . Функция глОтобратьПоКолонке(ТЗВход,Колонка,Значение) Экспорт //возвращает отобранную ТЗ Перем ТЗ, ТЗВрем; ТЗВход.Выгрузить(ТЗ); //вот здесь, сволочь! . ..функция возвращает ТЗ, отфильтрованную по заданному значению заданной колонки... . можно конечно ускорить, заменив выгрузку на ТЗ.Заполнить(ТЗВход) . может еще что есть для ускорения...? может под это дело как-то подойдкт индексированная таблица? |
|||
1
DEVIce
03.12.11
✎
10:20
|
Индексированная таблица как-то подойдет - да. :)
|
|||
2
Mikeware
03.12.11
✎
10:22
|
Уточни задачу
|
|||
3
zak555
03.12.11
✎
10:22
|
лучше забить на это дело и пойти погулять
|
|||
4
DEVIce
03.12.11
✎
10:24
|
В ИТ вообще можно задать индекс, от фильтровать по нему и работать уже с использованием этого индекса, без всяких выгрузов в ТЗ и прочих извращений. Но я уже не помню как это точно сделать, давно 1сpp не баловался.
|
|||
5
Злопчинский
03.12.11
✎
10:27
|
(2) из большой ТЗ надо выдрать подмножество строк; строки попадающие в подмножество фильтруются по значению заданной колонки
//есть некая ТЗ ТЗподмножество = глОтобратьПоКолонке(ТЗ,"Контрагент",выбКонтрагент); - в ТЗподмножество будут только те строки исходной ТЗ, где ТЗ.Клиент=ВыбКлиент |
|||
6
Злопчинский
03.12.11
✎
10:28
|
тьху...
..где где ТЗ.Контрагент=ВыбКонтрагент |
|||
7
Mikeware
03.12.11
✎
10:28
|
ДобавитьИндекс / AddIndex
Описание: Добавляет индекс к таблице. Синтаксис: ДобавитьИндекс(стрИдентификатор, стрВыражение, [чТолькоУникальныеЗначения = 0]) Параметры * стрИдентификатор - строка, идентификатор создаваемого индекса; * стрВыражение - строка, индексное выражение. Индексное выражение состоит из списка идентификаторов колонок, разделённого запятыми. Если перед именем колонки стоит символ '-', то сортировка осуществляется в обратном порядке. Если перед именем колонки стоит символ '*', то сортировка осуществляется в по внутреннему представлению объекта. Если перед именем колонки стоит символ '#', то перед сравнением строк обрезаются пробелы слева и справа. Если перед именем колонки стоит символ '^', то строки сравниваются без учёта регистра. Модификаторы сортировки ('-', '*', "#", "^") можно использовать в любых сочетаниях. Индексное выражение может быть пустой строкой - это эквивалентно сортировке по номеру строки, или отсутствию сортировки (фильтр на такой индекс установить нельзя). * чТолькоУникальныеЗначения - число. Если 1, то в индекс попадут только строки, содержащие уникальные значения индекса. Строки с повторяющимися индексами будут проигнорированы, и в операции перебора строк, суммирования, свёртки, выгрузки, загрузки не попадут. Возвращаемое значение: число, номер созданного индекса. УстановитьФильтр / SetFilter Описание: устанавливает динамический фильтр на таблицу по указанному индексу. Фильтр влияет на работу методов: ВНачало(), ВыбратьСтроки(), ВКонец(), ПолучитьСтроку(), СледующаяСтрока(), ПредыдущаяСтрока(),Свернуть(),Итог(), ЗаполнитьКолонку(), Выгрузить(), Загрузить(), Объединить(). Синтаксис: УстановитьФильтр(КлючМин, КлючМакс, [Индекс = ""], [чТолькоУникальные = 0]) Параметры * КлючМин - нижняя граница фильтра. Задаётся так же, как в методе НайтиСтроку(). * КлючМакс - верхняя границы фильтра. Задаётся так же, как в методе НайтиСтроку(). * Индекс - идентификатор или номер индекса. По умолчанию используется основной индекс. * чТолькоУникальные - число, если 1 - то в выборку попадут только строки с уникальным значением ключа. Если индекс построен по одной колонке, то в качестве ключей можно использовать значение колонки. Если же индекс по нескольким колонкам, то ключ должен быть СписокЗначений, содержащий значения ключевых колонок, заданных в методе ДобавитьИндекс(). |
|||
8
Злопчинский
03.12.11
✎
10:29
|
исходная ТЗ м.б. от одной до нескольких тысч строк
|
|||
9
Mikeware
03.12.11
✎
10:32
|
(5) Нечто типпо
ИТЗ.Загрузить(ВходящаяТЗ) ИТЗ.ДобавитьИндекс("ПоКонтре","Контрагент",0); ИТЗ.УстановитьФильтр(ВыбКонтрагент,ВыбКонтрагент,"ПоКонтре"); ИТЗ.Выгрузить(ВыходнаяТЗ) |
|||
10
Mikeware
03.12.11
✎
10:33
|
Только можно и не загружать-выгружать, а просто накладывать фильтр, и работать как с обычной ТЗ. Зависит от задач
|
|||
11
Злопчинский
03.12.11
✎
10:33
|
(7) а по товим оценкам замена на (7) даст существенный прирост скорости?
. добавляю индекс из одной колонки, потом ставлю фильтр, и иду простой выборкой по таблице - получаю только то, что попало в фильтр...? . а если второй раз устанавливаю фильтр - первый фильтр сбросится и установится второй..? |
|||
12
Mikeware
03.12.11
✎
10:35
|
(11) Ебстебственно...
На больших таблицах прирост скорост скорости большой. На мелких - есть даже падение. Таки накладняк :-) |
|||
13
Злопчинский
03.12.11
✎
10:38
|
(10) > а просто накладывать фильтр, и работать как с обычной ТЗ.
- да, это подойдет... . а после наложения фильтра - исходный порядок строк останется...? |
|||
14
Mikeware
03.12.11
✎
10:40
|
(13) Вроде не гарантируется.
Но ставь составной индекс, проблем-то.. |
|||
15
Злопчинский
03.12.11
✎
10:41
|
(12) в принципе можно и штатной ТЗ обойтись...
. ТЗ.Сортировать("Контрагент,ОригинальныйПорядокСтрок"); - потом для контрагента - позиционироваться поиском на нужного, и идти обычной выборкой пока контрагент не сменится.. - при таком подходе, скорее всего наверное производительность будет соизмерима с индексированной... |
|||
16
Mikeware
03.12.11
✎
10:42
|
(15) Способ фактически тот же, но на больших таблицах индексированная быстрее.
|
|||
17
Mikeware
03.12.11
✎
11:09
|
Ну и? помощь нужна еще, или победил?
|
|||
18
Злопчинский
03.12.11
✎
11:13
|
(16) а, блин, как в (15) не получится.. нужен итог по числовой колонке...
ИТЗ дает Итог() по фильтру - это хорошо... . (14) составной индекс - это как будет..? надо чтобы был фильтр наложен, и строки шли по оригинальном упорядку строк (колонка, например, "ОПС") - мог усоздать составнйо индекс, а фильтровать по только по однйо части составного индекса..? типа так? |
|||
19
Mikeware
03.12.11
✎
11:16
|
(18) Нет, фильтровать надо по всему индексу.
Но минимальный ключ у тебя будет {Контрагент,0}, а максимальный {Контрагент, КолСтрок_ИТЗ} |
|||
20
DEVIce
03.12.11
✎
11:30
|
(14). Остается, потому что существует индекс по умолчанию.
|
|||
21
DEVIce
03.12.11
✎
11:33
|
(18). МОжно создать сразу несколько индексов. Я делал, например, по контрагенту и по контрагенту/договору. Потом выборкой проходил по контрагенту и следующей по контрагенту/договору. Очень удобно. В случае с ТЗ пришлось бы делать одну ТЗ копированием другой и потом сварачивать по контрагенту, а затем реализовавать обход с поиском по двум полям в первоначальной. А если таких полей 5-6? Вооот. Тут ИТ здорово помогает, это кроме скорости работы.
|
|||
22
Mikeware
03.12.11
✎
11:34
|
(20) Индекс по умолчанию - по номеру строки. Ты назначаешь новый индекс. Который к индексу по умолчанию никакого отношения не имеет. В общем-то, по всем правилам, порядок сток в выборке при отсутсвии явного указания сортировки - не гарантируется. Судя по опыту работы с ИТЗ - на "по умолчанию" в ней лучше не полагаться. Судя по стилю, писали люди, помнящие анекдот про яблоки и буратино....
|
|||
23
DEVIce
03.12.11
✎
11:40
|
(22). Это на до у Диркса уточнить. Насколько помню один индекс не влияет на другой.
|
|||
24
DEVIce
03.12.11
✎
11:41
|
(22). Что за анекдот?
|
|||
25
Mikeware
03.12.11
✎
11:42
|
(23) Естественно, не влияет. О чем я и говорю - что "индекс по умолчанию" - по номеру строки - никак не повлияет на построение индекса по контре. Т.е. порядок в доступе по индексу по контре никак не связан с порядком строк. он _может_ быть построен в "порядке исходных строк", но не обязан.
|
|||
26
Mikeware
03.12.11
✎
11:43
|
(24) Буратино дали три яблока. Два он съел. Сколько яблок осталось у Буратино? Думаете одно? Ничего подобного. Никто не знает сколько у него уже было яблок до этого. Мораль: всегда обнуляйте переменные!
© |
|||
27
DEVIce
03.12.11
✎
11:45
|
(25). Ну так ты раз отсортируй и порядок потом не изменится при манипуляции с другими индексами.
|
|||
28
Mikeware
03.12.11
✎
11:45
|
(27) Не уверен, и поставщиком это нигде не описано. на неописанные вещи предпочитаю не опираться....
|
|||
29
DEVIce
03.12.11
✎
11:46
|
(26). "Барутино, предположим ты дал 2 яблока некту, сколько у тебя останется? Да я не дам 2 яблока некту - хоть он дерись" :)
|
|||
30
DEVIce
03.12.11
✎
11:47
|
Плохо что Алексей по форумам не лазит - он бы сейчас точно сказал. :)
|
|||
31
Злопчинский
03.12.11
✎
11:48
|
(19) не понял..а!! и будет тогда в фильтре упорядочено от Мин до Макс индекса?
|
|||
32
DEVIce
03.12.11
✎
11:51
|
(31). А вот ту не обязательно, сортировать все-таки надо.
|
|||
33
DEVIce
03.12.11
✎
11:53
|
(31). Вообще на www.1cpp.ru написано подробнее.
|
|||
34
Mikeware
03.12.11
✎
11:59
|
(32) Вот тут как раз обязательно. Ибо индекс
|
|||
35
DEVIce
03.12.11
✎
12:01
|
(34). Ты меня запутал :). По умолчанию тоже индекс, с техническо точки зрения точно такой же, что и ручками добавленный.
|
|||
36
DEVIce
03.12.11
✎
12:02
|
Все, я поехал в танчики рубиться. С индексами вашими тут в субботу понимаешь :)
|
|||
37
Mikeware
03.12.11
✎
12:05
|
(35) "Индекс по умолчанию" не имеет никакого отношения к вновь построенному индексу.
Если индекс по {Контра, номер строки}, то и сортировка никакая не нужна - при доступе по индексу доступ будет эквивалентенн сортировке сначала по контре, внутри контры - по номеру строки. Если индекс только по контре - то при доступе по индексу - по контре будут отсортированы, а как в пределах одной контры - не гарантировано. Может, по номеру строки, а может как-то иначе. |
|||
38
Злопчинский
03.12.11
✎
13:16
|
(37) по идее, нормально получится с составным индексом. Если прирост ощутимый будет - то ок. Штатный вариант подошел бы, но блин итог по таблице нужен по фильтру по количеству. Спасибо за помощь всем...
. пошел руками поработаю - унитаз попробую починить.. это для меня круто! |
|||
39
Torquader
03.12.11
✎
22:58
|
А если сразу при создании ТЗ отбирать по нужной колонке ?
|
|||
40
Aleksey
03.12.11
✎
23:03
|
Я для таких задач юзаю группировать
ИТЗ.Группировать("Контрагент:Контрагент","КлонкаССуммаЕслиНадо"); А дальще хоть поиск (ТЗ маленькая) Хоть перебор ИТЗ.ВыбратьСтроки(); Пока ИТЗ.ПолучитьСтроку()=1 цикл //вторая ТЗ по этому контру ВтораяТЗ=ИТЗ.тзПотомки; ВтораяТЗ.ВыбратьСтроки(); .... |
|||
41
Aleksey
03.12.11
✎
23:04
|
||||
42
Злопчинский
04.12.11
✎
15:27
|
(40) каков порядок строк в ТЗпотомки?
|
|||
43
Злопчинский
04.12.11
✎
17:28
|
(39) можно и так, попробую попозже... если ИТЗ не даст прироста планируемого
|
|||
44
Aleksey
04.12.11
✎
17:29
|
(42) Непроверял, скорее всего тот же что и был.
В любом случае ВтораяТЗ=ИТЗ.тзПотомки; - это ТЗ, а значит ВтораяТЗ.Сортировать("нужнаяКолонка") будет работать |
|||
46
Злопчинский
04.12.11
✎
17:48
|
(44) да, сейчас пробую; запрограммил, запущу на тестовый длительный просчет - если где-то криво - выплывет сразу...
. подошло создание фильтра, потом группировка по фильтру с итогом по количеству, а далее "шатный" алгоритм: прямо берется тзПотомки по ссылке и сортируется по ОПС (оригинальный порядок строк).. сейчас прроверим... |
|||
47
Злопчинский
04.12.11
✎
17:49
|
такс.. не получается с группировкой...
|
|||
48
Злопчинский
04.12.11
✎
17:50
|
а! при Группировать предварительно индекс не надо сосздавать!
|
|||
49
Злопчинский
04.12.11
✎
17:55
|
О! запустился.. чисто визуально даже видно вроде как есть ускорение...
|
|||
50
Злопчинский
04.12.11
✎
18:01
|
итого получилось так, как посоветовали выше - легло иделаьно в код
. ИТЗ = СоздатьОбъект("ИндексированнаяТаблица"); ИТЗ.Загрузить(ТЗгтд); ИТЗ.Группировать("ФильтрНоменклатура: Номенклатура","Количество"); // //найдем и спозиционируемся Если ИТЗ.НайтиСтроку("ФильтрНоменклатура", текНоменклатура, 0, 1) = 0 Тогда //сюда попадать не должны Сообщаить("Алярм-001!","!!!"); Продолжить; КонецЕсли; ТЗгтдНоменклатура = ИТЗ.тзПотомки; Если ИТЗ.Количество < ОстПогКоличество Тогда |
|||
51
Aleksey
04.12.11
✎
18:12
|
Угу самому иногда не хватает в 8-ке такой же легкой группировки
|
|||
52
Злопчинский
04.12.11
✎
20:04
|
(51) а что, в 8-ке нельзя ТЗ подсунуть в запрос и получить на выходе что надо...?
|
|||
53
Дядя Васька
04.12.11
✎
20:11
|
(52) Там и без запроса можно по нескольким полям отобрать. Метод НайтиСтроки(), и индексы тоже есть.
|
|||
54
Aleksey
04.12.11
✎
20:39
|
(53) Вопрос то не в найти строки, а именно группировки. Т.е. построение дерево
Очень часто нужно с плюсиками выводить отчет с кучей вложенной группировки, и ИМХО метод "НайтиСтроки()" будет сильно затратен, не говоря уж о том, что для начало нужно получить те значения которые нужно искать |
|||
55
Злопчинский
04.12.11
✎
21:19
|
ух, блин, переколбасил весь алгоритм... ща буду тестить...
|
|||
56
Злопчинский
04.12.11
✎
21:40
|
так, блин, непонятно...
чегой-то не видно после группировки чтобы была ТЗПотомки |
|||
57
Злопчинский
04.12.11
✎
21:40
|
а кто объяснит, почему вот это нифига не работает...
. //******************************************* Процедура Сформировать() ТЗ = СоздатьОбъект("ТаблицаЗначений"); ТЗ.НоваяКолонка("Ключ","Строка"); ТЗ.НоваяКолонка("Значение","Строка"); ТЗ.НоваяКолонка("Количество","Число"); ТЗ.НоваяСтрока(); ТЗ.Ключ = "строка1"; ТЗ.Значение = "значение1"; ТЗ.Количество = 1; ТЗ.НоваяСтрока(); ТЗ.Ключ = "строка1"; ТЗ.Значение = "значение2"; ТЗ.Количество = 3; ТЗ.НоваяСтрока(); ТЗ.Ключ = "строка2"; ТЗ.Значение = "значение1"; ТЗ.Количество = 2; ИТЗ = СоздатьОбъект("ИндексированнаяТаблица"); ИТЗ.Загрузить(ТЗ); ИТЗ.Группировать("ФильтрТипа: Ключ","Количество"); ИТЗ.ВыбратьСтроку(,); КонецПроцедуры |
|||
58
Злопчинский
04.12.11
✎
22:22
|
так, уже объяснили! ура!
|
|||
59
Злопчинский
05.12.11
✎
01:51
|
Если индекс составной, например, "ГТД,Документ"
то как на ИТЗ наложить фильтр, чтобы осталась выборка только конкретного ГТД..??? . люди, ау!!! |
|||
60
ОбычныйЧеловек
05.12.11
✎
01:54
|
(59) Если хочешь получить ответ то лучше сюда http://www.1cpp.ru/forum/YaBB.pl
|
|||
61
Дядя Васька
05.12.11
✎
02:01
|
(54) Ну вроде как ветка началась именно с этого. К сортировкам с группировками пришли уже после, дабы избежать тормозов при копировании. НайтиСтроки() ничего не копирует, просто возвращает массив ссылок на нужные строки, что по сабжу и требовалось.
|
|||
62
Злопчинский
05.12.11
✎
02:21
|
А вот вопрос Индекс по "Документ", где документ - любого вида - как упорядочивает..?
|
|||
63
Злопчинский
05.12.11
✎
02:21
|
(61) убить нахрен надо тех кто доки пишет невразумительные...
|
|||
64
Vakhrin
05.12.11
✎
03:13
|
а еще выборки разные из больших ТЗ можно вот так ускорить: http://vakhrin.com/?p=19#more-19 ;)
|
|||
65
КонецЦикла
05.12.11
✎
03:32
|
(59) Передавать список значений (вроде так обычно делается)
Например для поиска: ИТЗУпаковки.ДобавитьИндекс("ИндТовар", "Товар,Серия,СрокГодности"); ... Спис = СоздатьОбъект("СписокЗначений"); Спис.ДобавитьЗначение(ТекТовар, "Товар"); Спис.ДобавитьЗначение(ТЗРезервов.Серия, "Серия"); Спис.ДобавитьЗначение(ТЗРезервов.СрокГодности, "СрокГодности"); НомСтр = ИТЗУпаковки.НайтиСтроку("ИндТовар", Спис, , 1); По фильтрам нету, сорри, как-то обходился все время без них :) Если есть какой-то большой набор данных, обрабатываемый многократно... ну типа в качестве бреда, не будет ли быстрее создать временную таблицу SQL или чо там у тебя, и делать выборку по индексу? |
|||
66
Злопчинский
05.12.11
✎
03:43
|
Отдельная благодарность Aleksey'ю за оказанные помощь/консультации!!!
оееееееееееееееееееее! хренячит быстро офигенно! не то что на штатных ТЗ (хотя логику сохранил практически одинаковую). Реальный выигрыш по предварительным замерам на массовом перепроведении будет примерно в 5 раз... как минимум.. уаааааааааааааа! я ж теперь в два раза больше сена накосю!!! |
|||
67
Злопчинский
05.12.11
✎
03:48
|
(65) предварительные исследования показали что Ус фильтром не получится так (УстановитьФильтр), если надо наложить фильтр на составнйо индексс пропуском полей индекса - использовали ИТЗ.Подмножество().
. про временную таблицу SQL - это мысль, конечно, но а) база дбфная, придется изворачиваться нескульными провайдерами б) есть сомнения что будет ощутимый прирост.. индексированная ТЗ - имхо почти то же самое... . а вот перевести на прямые запросы РассчитатьИтогиНа() - это можно попробовать (но опять же на дбф, у меня движок сетевой нескульный, а то ябы давно на скуль перевел, благо и скуль лицензионный есть и все остальное). . опять же - еще ускорение РассчитатьРегистрыНа для перепроведения задним числом (ЗЧ) даст наверное период итогов на 5 дней - но это уже на след.выходные буду пробовать... |
|||
68
Злопчинский
05.12.11
✎
03:51
|
хотя хз.. эксперимент не сильно чистый, сисадмин учерась дефраг на диски с базой сделал.. может еще и это эффект дало... ;-) хотя вряд ли что это сильно повлияло.. ибо диск под базу выделен отдельный физический и почти там ничего больше и не лежит/неиспользуется...
. а вот интересно.. размер кластера при работе на дбфе по идее может дать кое-какие профиты...? |
|||
69
Злопчинский
05.12.11
✎
05:22
|
в итоге: реальный выигрыш получился раза в три... именно на операциях с ТЗ...
на фоне общих временных затрат выигрыш не так существене.. все сжирает временные итоги РассчитатьРегистрыНа() - как это ускорить...? |
|||
70
Злопчинский
05.12.11
✎
06:05
|
мдя... последнйи релиз 1С++ датирован 13.08.2010 г.
скоро полтора года как ничего не изменилось... можно считать, что прект умер. пора линять на снеговика... |
|||
71
SnarkHunter
05.12.11
✎
06:57
|
Последний релиз 1С++ (3.2.3.17) датирован 01.12.2011...
|
|||
72
SnarkHunter
05.12.11
✎
06:58
|
>> все сжирает временные итоги РассчитатьРегистрыНа() - как это ускорить
Прямыми запросами... |
|||
73
Злопчинский
05.12.11
✎
07:12
|
меня плющит..?
на 1Сpp в снапшотах последний 3.2.2 http://s017.radikal.ru/i403/1112/33/b62f80e0b087.png |
|||
74
Злопчинский
05.12.11
✎
07:13
|
(72) вообщем это понятно.. ;-) но вот в частностях...
|
|||
75
SnarkHunter
05.12.11
✎
07:30
|
(73)Релизы выкладываются на форуме в специальной ветке...
|
|||
76
Злопчинский
05.12.11
✎
07:33
|
(75) ну хоть бы написали на сайте в разделе снапшотов ссылку на форум
кто в лес, кто по дрова... |
|||
77
SnarkHunter
05.12.11
✎
07:38
|
(76)Что есть, то есть... :-)
|
|||
78
ЧеловекДуши
05.12.11
✎
08:08
|
(73)Это старая информация и не соответствует действительности :)
|
|||
79
Злопчинский
05.12.11
✎
13:42
|
(78) ну уж если на офиц.странице актуальность не поддерживают - проект тихонько умирает...
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |