![]() |
![]() |
![]() |
|
Накопительный итог 1С | ☑ | ||
---|---|---|---|---|
0
ОператорПК
07.02.11
✎
16:16
|
Здравствуйте.
Стоит задача получить лесенку (накопительный итог) по последовательности документов. Поясню напримере - есть исходная таблица произвольных документов: РТиУ №01 100 РТиУ №02 500 РТиУ №03 80 РТиУ №04 200 Нужна таблица: РТиУ №01 100 880 РТиУ №02 500 780 РТиУ №03 80 280 РТиУ №04 200 200 Какой самый быстрый способ ее получить? Сейчас используется конструкция: ВЫБРАТЬ ВТ2.Регистратор, СУММА(ВТ3.СуммаУпр) КАК СуммаУпр ПОМЕСТИТЬ ВТ42 ИЗ ВТ2 КАК ВТ2 ЛЕВОЕ СОЕДИНЕНИЕ ВТ2 КАК ВТ3 ПО ВТ2.МоментВремени <= ВТ3.МоментВремени СГРУППИРОВАТЬ ПО ВТ2.Регистратор Но для большого количества документов работает дико медленно. Собственно вопрос каким запросом можно получить тот – же результат за меньшее время? |
|||
1
mikecool
07.02.11
✎
16:19
|
выбрать в ТЗ, пробежаться посчитать?
|
|||
2
Axel2009
07.02.11
✎
16:19
|
ТЗ обработать?
|
|||
3
Asmody
07.02.11
✎
16:19
|
самый быстрый - правильно использовать регистры
|
|||
4
ОператорПК
07.02.11
✎
16:20
|
Запрос состоит из множества пакетов (этот один из промежуточных).
|
|||
5
zak555
07.02.11
✎
16:20
|
ты бы хотть так написал бы :
РТиУ №01 200 200 РТиУ №02 80 280 РТиУ №03 500 780 РТиУ №04 100 880 |
|||
6
ОператорПК
07.02.11
✎
16:21
|
(5) мне нужно так как написано в (0). хотя это не принцыпиально.
|
|||
7
Axel2009
07.02.11
✎
16:24
|
индексы по моментвремени+суммаупр попробовать
|
|||
8
ОператорПК
07.02.11
✎
16:26
|
(7) по моменту времени нет индексации.
|
|||
9
shuhard
07.02.11
✎
16:29
|
(8) Рг накопления прикрутить уже поздно ?
|
|||
10
ОператорПК
07.02.11
✎
16:30
|
(9) да
|
|||
11
shuhard
07.02.11
✎
16:32
|
(10) та же 25 Гбайт мясная база ?
|
|||
12
Axel2009
07.02.11
✎
16:32
|
условия сделать на дату + ссылку и по ним индексы
|
|||
13
ОператорПК
07.02.11
✎
16:33
|
(11) нет 150 Гб (наш филиальчеГ) :))
|
|||
14
acsent
07.02.11
✎
16:36
|
(9) Чем регистр накопления поможет?
|
|||
15
ОператорПК
07.02.11
✎
16:40
|
(12) попробывал, не канает...
|
|||
16
Axel2009
07.02.11
✎
16:41
|
(15) чем не канает?
|
|||
17
zak555
07.02.11
✎
16:43
|
а если сделать так для печатной формы
цикл Группировка(1) КонОстВышестоящей = ЗАпрос.Сальдо; Цикл ГРуппировка(2) КонОстТекДок = Запрос.Сальдо - КонОстВышестоящей |
|||
18
ОператорПК
07.02.11
✎
16:43
|
(16) быстрее не стало работать.
|
|||
19
ОператорПК
07.02.11
✎
16:44
|
(17) результат запроса в (0) не конечный он еще многократно обрабатывается.
|
|||
20
73
07.02.11
✎
16:45
|
||||
21
zak555
07.02.11
✎
16:45
|
(19) что ещё ?
|
|||
22
fisher
07.02.11
✎
16:45
|
Навскидку:
http://www.sql.ru/faq/faq_topic.aspx?fid=125 |
|||
23
ОператорПК
07.02.11
✎
16:46
|
(20) то же самое...
|
|||
24
73
07.02.11
✎
16:48
|
(23) Что то же? Ты хоть почитай. Условие как у тебя. Решение там - пост 10.
|
|||
25
shuhard
07.02.11
✎
16:48
|
(22) предлагаешь курсор сделать ?
|
|||
26
ОператорПК
07.02.11
✎
16:50
|
(24) тот же коннект ПериодыИзменения.Период >= Регистр.Период
что нового я там должен увидить? |
|||
27
ОператорПК
07.02.11
✎
16:51
|
(25) чево за курсор как по одноэсовски будет?
|
|||
28
Axel2009
07.02.11
✎
16:51
|
(18) и какой же индекс был использован?
|
|||
29
73
07.02.11
✎
16:52
|
(26) А что ты хочешь увидЕть?
Если решение - то оно там. Что ещё? |
|||
30
fisher
07.02.11
✎
16:53
|
(26) Да, в самом деле... Извини. Мож в комментах что полезное.
|
|||
31
ОператорПК
07.02.11
✎
16:53
|
(28)
ИНДЕКСИРОВАТЬ ПО Регистратор, СуммаУпр -только не понятно как этот индекс может ускорить соединение по МоментВремени. |
|||
32
fisher
07.02.11
✎
16:55
|
(30) + Мда... Ничего применимого к 1С в комментах не нашел. Все более быстрые способы к 1С не применимы.
|
|||
33
ОператорПК
07.02.11
✎
16:58
|
(29) обычно одну и туже задачу можно решить разными способами вот я и спрашиваю про другой способ т.к. этот способ давольно медленно работает в моем случае.
|
|||
34
shuhard
07.02.11
✎
16:59
|
(27)[как по одноэсовски будет]
ни как отдаленный аналог курсора - временная таблица, её ты уже использовал |
|||
35
Axel2009
07.02.11
✎
16:59
|
(31) если не помог, значит ничего больше не поможет..
если только не извращаться и уменьшать количество обрабатываемых строк.. в цикле там обрабатывать.. |
|||
36
shuhard
07.02.11
✎
17:00
|
(33) дык вариант с накоплением итога по регистратору в Рг накопления ты отверг
|
|||
37
ОператорПК
07.02.11
✎
17:03
|
(36) как мне его накопить? допустим есть пары Договор+Контрагент один пользователь захочет посмотреть в разрезе одного договора другой в разрезе всех.... у меня нет четкого соответствия Регистратор-Накопительный итог.
|
|||
38
ОператорПК
07.02.11
✎
17:03
|
Договор+Контрагент=Договор+регистратор сори...
|
|||
39
fisher
07.02.11
✎
17:04
|
(33) Судя по всему, на голом SELECTе быстрее никак. В T-SQL более быстрые варианты реализуют курсорами и DML.
|
|||
40
Axel2009
07.02.11
✎
17:08
|
(38) не зная полной задачи , трудно посоветовать. может удастся както обойти этот пересчет. и сколько документов попадает под пересчет обычно?
|
|||
41
ОператорПК
07.02.11
✎
17:10
|
40 тыс. документов "на входе".
|
|||
42
Axel2009
07.02.11
✎
17:12
|
и сколько отрабатывает по времени? и если "на входе" будет 1000 доков, скока будет отрабатывать?
|
|||
43
Axel2009
07.02.11
✎
17:13
|
800млн строк обработать - не шухры мухры =)
|
|||
44
ОператорПК
07.02.11
✎
17:13
|
(42) минут 10-20 не замерял точно.
|
|||
45
Axel2009
07.02.11
✎
18:01
|
в таблице 890 строк
Запрос = Новый Запрос; Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 20000 | Продажи.Регистратор КАК Регистратор, | СУММА(Продажи.Стоимость) КАК Стоимость |ПОМЕСТИТЬ ТестОбороты |ИЗ | РегистрНакопления.Продажи КАК Продажи | |СГРУППИРОВАТЬ ПО | Продажи.Регистратор |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ТестОбороты_1.Регистратор, | СУММА(ТестОбороты_2.Стоимость) КАК Стоимость |ИЗ | ТестОбороты КАК ТестОбороты_1 | ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТестОбороты КАК ТестОбороты_2 | ПО ТестОбороты_1.Регистратор >= ТестОбороты_2.Регистратор | |СГРУППИРОВАТЬ ПО | ТестОбороты_1.Регистратор |УПОРЯДОЧИТЬ ПО Стоимость"; ТЗ = Запрос.Выполнить().Выгрузить(); запрос отработал 1,4с Запрос = Новый Запрос; Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц; Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 20000 | Продажи.Регистратор КАК Регистратор, | СУММА(Продажи.Стоимость) КАК Стоимость |ПОМЕСТИТЬ НД1 |ИЗ | РегистрНакопления.Продажи КАК Продажи | |СГРУППИРОВАТЬ ПО | Продажи.Регистратор; |ВЫБРАТЬ ПЕРВЫЕ 0 Регистратор, Стоимость ПОМЕСТИТЬ КД2 ИЗ НД1"; Запрос.Выполнить(); ИмяИтоговойТаблицы = ""; Пока Истина Цикл ОбработкаПрерыванияПользователя(); Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 200 | Регистратор, Стоимость |ПОМЕСТИТЬ ПД |ИЗ НД1 |УПОРЯДОЧИТЬ ПО Регистратор; | |ВЫБРАТЬ ПД1.Регистратор, СУММА(ПД2.Стоимость)+ЕСТЬNULL(ДопСумма.Стоимость, 0) КАК Стоимость |ПОМЕСТИТЬ КД1 |ИЗ ПД КАК ПД1 ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПД КАК ПД2 ПО ПД1.Регистратор >= ПД2.Регистратор |ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ МАКСИМУМ(Стоимость) КАК Стоимость ИЗ КД2) КАК ДопСумма ПО ИСТИНА |СГРУППИРОВАТЬ ПО ПД1.Регистратор, ДопСумма.Стоимость |ОБЪЕДИНИТЬ ВСЕ |ВЫБРАТЬ Регистратор, Стоимость ИЗ КД2; | |ВЫБРАТЬ НД1.Регистратор КАК Регистратор, НД1.Стоимость КАК Стоимость |ПОМЕСТИТЬ НД2 |ИЗ НД1 ЛЕВОЕ СОЕДИНЕНИЕ КД1 ПО НД1.Регистратор = КД1.Регистратор |ГДЕ КД1.Регистратор ЕСТЬ NULL; |УНИЧТОЖИТЬ НД1; |УНИЧТОЖИТЬ КД2; |УНИЧТОЖИТЬ ПД; |ВЫБРАТЬ ПЕРВЫЕ 1 Регистратор ИЗ НД2"; ВыборкаПроверка = Запрос.Выполнить().Выбрать(); Если Не ВыборкаПроверка.Следующий() Тогда ИмяИтоговойТаблицы = "КД1"; Прервать; КонецЕсли; Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 200 | Регистратор, Стоимость |ПОМЕСТИТЬ ПД |ИЗ НД2 |УПОРЯДОЧИТЬ ПО Регистратор; | |ВЫБРАТЬ ПД1.Регистратор, СУММА(ПД2.Стоимость)+ДопСумма.Стоимость КАК Стоимость |ПОМЕСТИТЬ КД2 |ИЗ ПД КАК ПД1 ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПД КАК ПД2 ПО ПД1.Регистратор >= ПД2.Регистратор |ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ МАКСИМУМ(Стоимость) КАК Стоимость ИЗ КД1) КАК ДопСумма ПО ИСТИНА |СГРУППИРОВАТЬ ПО ПД1.Регистратор, ДопСумма.Стоимость |ОБЪЕДИНИТЬ ВСЕ |ВЫБРАТЬ Регистратор, Стоимость ИЗ КД1; | |ВЫБРАТЬ НД2.Регистратор КАК Регистратор, НД2.Стоимость КАК Стоимость |ПОМЕСТИТЬ НД1 |ИЗ НД2 ЛЕВОЕ СОЕДИНЕНИЕ КД2 ПО НД2.Регистратор = КД2.Регистратор |ГДЕ КД2.Регистратор ЕСТЬ NULL; |УНИЧТОЖИТЬ НД2; |УНИЧТОЖИТЬ КД1; |УНИЧТОЖИТЬ ПД; |ВЫБРАТЬ ПЕРВЫЕ 1 Регистратор ИЗ НД1"; ВыборкаПроверка = Запрос.Выполнить().Выбрать(); Если Не ВыборкаПроверка.Следующий() Тогда ИмяИтоговойТаблицы = "КД2"; Прервать; КонецЕсли; КонецЦикла; Запрос.Текст = "ВЫБРАТЬ Регистратор, Стоимость ИЗ " + ИмяИтоговойТаблицы + " УПОРЯДОЧИТЬ ПО Регистратор"; ТЗ = Запрос.Выполнить().Выгрузить(); отработал за 0.6сек на количестве данных 40000 будет еще существеннее. за минутку может и отработать.. быстрее хз как =) |
|||
46
IKSparrow
07.02.11
✎
19:09
|
А разве через таблицу оборотов не получается искомое?
|
|||
47
Axel2009
07.02.11
✎
19:50
|
(46) вопрос не в искомом, а в скорости получения искомого.
|
|||
48
fisher
08.02.11
✎
10:54
|
(45) Вопрос, как поведет себя такая методика на многомиллионных таблицах в сравнении с обычным методом. Сравни, плиз, с шагом в лимонов 5 строк несколько замеров. У тебя ведь всё готово уже. Очень интересно тенденцию отследить.
Насколько замедлит работу многократное переливание туда-сюда огромной исходной таблицы (с выкусыванием обработанных порций). Ведь замедление этой операции замедляет работу всего алгоритма в геометрической прогрессии. Хочется понять, насколько метод применим на больших таблицах. Кстати, ЛЕВОЕ СОЕДИНЕНИЕ ПО ИСТИНА можно заменить на стандартную запись декартова произведения в SQL - просто указав вторую таблицу через запятую без всяких соединений. А Не ВыборкаПроверка.Следующий() на Запрос.Выполнить().Пустой() |
|||
49
Axel2009
08.02.11
✎
10:59
|
(48) если будет 1млн строк, то присоединение из (0) даст обработку в 500 трл строк. сервер сдохнет..
а на счет "Пустой" тоже можно =) |
|||
50
fisher
08.02.11
✎
11:01
|
(49) Вот не факт, что сдохнет. Тут практика важнее домыслов.
|
|||
51
Axel2009
08.02.11
✎
11:01
|
(49) ошибся, в 500блн строк
|
|||
52
Axel2009
08.02.11
✎
11:01
|
(50) у сервера стока оперативки нетю..
|
|||
53
Axel2009
08.02.11
✎
11:02
|
(51) не, трл =) чета засчитался. ща проверю на более больших данных
|
|||
54
Axel2009
08.02.11
✎
11:04
|
(50) ЗЫ на млн строк даж пробовать не буду =) сами пробуйте если хотите.
|
|||
55
fisher
08.02.11
✎
11:10
|
Ну, можно на меньших объемах. Главное хоть какой-то тренд наметить.
|
|||
56
Axel2009
08.02.11
✎
11:19
|
скульсервак (база на скуле, новые тесты). до этого была файловая база
проверка на 1000 строк одним запросом: 0.55сек обработкой по 200 строк: 0.77сек обработкой по 500 строк: 1.3сек проверка на 16 000 строк одним запросом: 82сек обработкой по 200 строк: 17сек обработкой по 500 строк: 12.7сек обработкой по 1000 строк: 13.1сек |
|||
57
fisher
08.02.11
✎
11:29
|
Можно было бы полный аналог курсоров забабахать на порционных выборках (как 1С и делает в своих системных механизмах). Без переливания туда-сюда больших объемов.
Просто выбирать порции из последовательных диапазонов исходной таблицы по нужному ключу, обрабатывать и результаты накапливать. Извечная проблема с накоплением. Т.к. добавить в 1С строки во временную таблицу можно только её полным пересозданием... Сколько нужных вещей в эту фигню упирается... |
|||
58
fisher
08.02.11
✎
11:30
|
(56) Спасибо. В общем, в независимости от оптимальности второго метода, первый однозначно идёт в топку на больших объемах...
|
|||
59
Axel2009
08.02.11
✎
11:31
|
(57) да много чего можно было бы.. только запросы в 1с только те что T-SQL. а курсоры - это дело каждой СУБДшки.. поэтому и не делают
|
|||
60
fisher
08.02.11
✎
11:33
|
(57) + Но всё равно будет быстрее твоего варианта, хотя и сложнее...
|
|||
61
Axel2009
08.02.11
✎
11:34
|
(60) а я и не спорю. =) в части накопительных сумм ток у Оракла знаю есть такая приблуда..
|
|||
62
Axel2009
08.02.11
✎
11:34
|
(61)+ ну и следующий скуль обещают наваять.. в 10ке.. хотя бета уже есть, можно глянуть. но на 1с это не отразится =)
|
|||
63
fisher
08.02.11
✎
11:36
|
(59) T-SQL это как раз курсоры :) Это название диалекта MSSQL.
Речь не о курсорах, их понятно почему нет. Речь о возможности INSERTов во временные таблицы. Это кучу бы возможностей дало. |
|||
64
Axel2009
08.02.11
✎
11:39
|
(63) T-SQL - транзактСКЛ, стандарт собственно говоря,которая каждая СУБДшка должна поддерживать =)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |