powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Сравнение СУБД [игнор отключен] [закрыт для гостей] / быстрое получение остатков на дату
25 сообщений из 51, страница 2 из 3
быстрое получение остатков на дату
    #35017930
TORT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм... Понятно... Скажите, а на основе MQT(суммарных таблиц) Вы это не пытались организовать? Вот это было бы весьма интересно....
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35017982
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov Andrey

TORTВы тестировали данный подход? Если не серкНе только тестировал, но и промышленно эксплуатировал. :)
Присоединяюсь.
У меня это сделано на MS SQL на триггерах.
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35018024
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TORTСкажите, а на основе MQT(суммарных таблиц) Вы это не пытались организовать? Вот это было бы весьма интересно....Как я уже сказал - я не пытался проводить тесты и сравнивать различные варианты реализации. Ну а в первой половине девяностых материализованных представлений еще не было. Поэтому приходилось все делать руками. :)
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35023691
dekan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov Andrey.....у нас один исключительный случай, когда учетных единиц было мало (порядка сотни), а конкурирующих транзакций - много (до полусотни процессов и десятки тысяч операций в час у каждого). Тут задержки на блокировках становятся посущественней. Для этого случая был другой вариант, когда заполнением этой таблицы занимался отдельный фоновый процесс.

А нельзя ли поподробнее вот с этого места? Как избавились от блокировок?
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35024037
sqllex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 DobPilot
А как часто у вас движения происходят и сколько userAccount?
А то, например, в BOL MS SQL2005 есть примечание для Indexed View:
BOL
Indexed views typically do not improve the performance of the following types of queries:
-OLTP systems that have many writes.
-Databases that have many updates.
-Aggregations of data with a high degree of cardinality for the GROUP BY key. A high degree of cardinality means the key contains many different values.
....
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35025444
Alex S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По мотивам:
Bogdanov Andrey
Имеем таблицу
Код: plaintext
1.
2.
3.
4.
Остатки
Номенклатура ссылка
Значение число
Начало дата
Конец дата
При совершении движения в этой таблице у текущей записи по номенклатуре выставляется "Конец" и добавляется новая. Если в один день происходит несколько двжиений, то мы просто модифицируем запись текущую запись.
Таким образом число записей не превышает количества движений, а остаток на любой день достается запросом без суммирования:
Код: plaintext
select Значение from Остатки where Номенклатура=:id and Начало <= :data and Конец > :data
Наличие индексов делает запрос быстрым. Особые эстеты могут его оптимизировать.
Я не говорю, что это единственное верное решение, но в некоторых случаях оно работает очень хорошо.
На MSSQL есть решение быстрее:
Имеем таблицу
Код: plaintext
1.
2.
3.
4.
Остатки
Номенклатура ссылка
Значение число
Начало дата
выборка:
Код: plaintext
select top  1  Значение from Остатки where Номенклатура=:id and Начало <= :data order by Начало desc

На Oracle нет top 1 (rownum применить не получится без подзапроса).
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35025465
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex S
На MSSQL есть решение быстрее:
...
Код: plaintext
select top  1  Значение from Остатки where Номенклатура=:id and Начало <= :data order by Начало desc
На Oracle нет top 1 (rownum применить не получится без подзапроса).
а если надо остатки по нескольким счетам? по одному счету то редко когда нужно
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35026012
Alex S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergSuperа если надо остатки по нескольким счетам? по одному счету то редко когда нужно
Код: plaintext
1.
2.
select Kod
,(select top  1  Значение from Остатки where Номенклатура=Номенклатура.Номенклатура and Начало <= :data order by Начало desc) as Значение
from Номенклатура
но imho лучше сделать udf
Код: plaintext
1.
2.
select Kod
,Остаток(Номенклатура.Номенклатура,:data) as Значение
from Номенклатура
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35026098
!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
!
Гость
SergSuper Alex S
На MSSQL есть решение быстрее:
...
Код: plaintext
select top  1  Значение from Остатки where Номенклатура=:id and Начало <= :data order by Начало desc
На Oracle нет top 1 (rownum применить не получится без подзапроса).
а если надо остатки по нескольким счетам? по одному счету то редко когда нужно

Универсальный вариант:
Код: plaintext
1.
2.
3.
4.
select  name, value, from reminders r1 where date in ( select max(date) from  reminders r2 
where r2.acc=r1.acc)
and  acc in (  список необходимых  счетов).


Чем больше счетов в списке тем дольше будет работать.
Для каждого счета за одну дату должна быть одна запись об остатках.
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35026315
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex S
На MSSQL есть решение быстрее:
...Давайте не будем в эту тему тащить сравнение MSSQL и Oracle. Да к тому же с отсутствием конкретных цифр. Я не уверен, что приведенное вами решение будет быстрее, чем аналогичное Oracle'овое.

dekanА нельзя ли поподробнее вот с этого места? Как избавились от блокировок?
Ну так конфликт блокировок возникает только при попытке разными процессам модифицировать остаток по одной и той же учетной единице. Если модификацией остатков занимается выделенный процесс, то никакого конфликта у него с самим собой быть не может.
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35026605
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex S SergSuperа если надо остатки по нескольким счетам? по одному счету то редко когда нужно
Код: plaintext
1.
2.
select Kod
,(select top  1  Значение from Остатки where Номенклатура=Номенклатура.Номенклатура and Начало <= :data order by Начало desc) as Значение
from Номенклатура
но imho лучше сделать udf
Код: plaintext
1.
2.
select Kod
,Остаток(Номенклатура.Номенклатура,:data) as Значение
from Номенклатура

Это я всё знаю, спрашивал чтобы всем было понятно что с двумя датами проще :))
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35026617
Alex S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov Andrey Alex S
На MSSQL есть решение быстрее:
...Давайте не будем в эту тему тащить сравнение MSSQL и Oracle. Да к тому же с отсутствием конкретных цифр. Я не уверен, что приведенное вами решение будет быстрее, чем аналогичное Oracle'овое.
Топикстартер как раз хотел решений для различных СУБД. Быстрее - я имел ввиду не "MSSQL быстрее Oracle", а "реализация с одной датой и top 1 на MSSQL быстрее реализации с двумя датами на MSSQL". Тесты когда-то давно проводил, в итоге остановился на озвученном решении для MSSQL. Кроме того, с одной датой операция записи проще. Если будет время - постараюсь повторить тесты.
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35026646
Alex S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergSuper
Это я всё знаю, спрашивал чтобы всем было понятно что с двумя датами проще :))
А как это проще выглядит?
SergSuperпо одному счету то редко когда нужно
Кстати, в OLTP не так уж и редко
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35026792
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex Sа "реализация с одной датой и top 1 на MSSQL быстрее реализации с двумя датами на MSSQL". Тесты когда-то давно проводил, в итоге остановился на озвученном решении для MSSQL. Кроме того, с одной датой операция записи проще.Ну вторая дата - это избыточность данных и естественно, ее поддержка требует "накладных расходов". Но некоторые примущества две даты имеют. Например, просуммировать остатки по позициям на определенную дату (то есть любой аналитический запрос) будет попроще и, наверное, побыстрее даже в MS-SQL. Я MS-SQL-ким диалектом не владею. Как с помощью Top поизящней записать запрос нижеприведенному?
Код: plaintext
select sum(Значение) from Остатки where Начало<=:data and Конец > :data
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35027175
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex S SergSuper
Это я всё знаю, спрашивал чтобы всем было понятно что с двумя датами проще :))
А как это проще выглядит?

одна дата:
Код: plaintext
1.
2.
select Kod
,(select top  1  Значение from Остатки where Номенклатура=Номенклатура.Номенклатура and Начало <= :data order by Начало desc) as Значение
from Номенклатура
две даты:
Код: plaintext
1.
select Kod
, Значение from Остатки join Номенклатура on Остатки.Номенклатура=Номенклатура.Номенклатура and  :data between Начало and Конец
разница будет еще заметней если надо из таблицы Остатков взять еще поля
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35028382
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИМХО, остатки нужно хранить не по временным интервалам, а по определённому количеству записей между остатками. Т.о. мы получим более предсказуемую ситуацию.
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35028800
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
drevИМХО, остатки нужно хранить не по временным интервалам, а по определённому количеству записей между остатками. Т.о. мы получим более предсказуемую ситуацию.
продемонстрируйте, что ли...
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35029064
drev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergSuper drevИМХО, остатки нужно хранить не по временным интервалам, а по определённому количеству записей между остатками. Т.о. мы получим более предсказуемую ситуацию.
продемонстрируйте, что ли...

Допустим, такая структура.


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
table sales_details
(
    id int primary key,
    doc_id int,  --FK
    item_id int, --FK
    amount float
)

table summary
(
    id int primary key,
    start_date datetime,
    end_date datetime,
    counter int
)
table summary_details
(
    id int primary key,
    summary_id int, --FK
    item_id int, --FK
    amount float
)


Добавляем триггер на sales_details, который находит соответствующую запись в таблице summary, и либо инкрементирует counter, либо добавляет в таблицу summary новую запись (если значение поля counter достигло некоторого порога).

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

Если чаще требуются остатки по конкретному товару, то вместо двух последних таблиц получаем одну:


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
table summary
(
    id int primary key,
    start_date datetime,
    end_date datetime,
    counter int
    item_id int, --FK
    amount float
)
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35029427
Alex S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SergSuper...
Код: plaintext
1.
select Kod
, Значение from Остатки join Номенклатура on Остатки.Номенклатура=Номенклатура.Номенклатура and  :data between Начало and Конец
разница будет еще заметней если надо из таблицы Остатков взять еще поля
Ну незнаю, в таблице остатков у меня только Id номенклатуры, плоскость остатка, дата , два оборота и остаток. Все остальное в таблице номенклатуры, и так исторически складывается, что основная выборка идет по ней. Ну там, например, не закрытые счета такой-то группы. И одна UDF-ка "остаток" в перечне полей в select.
Bogdanov Andrey...Ну вторая дата - это избыточность данных и естественно, ее поддержка требует "накладных расходов". Но некоторые примущества две даты имеют. Например, просуммировать остатки по позициям на определенную дату (то есть любой аналитический запрос) будет попроще и, наверное, побыстрее даже в MS-SQL. Я MS-SQL-ким диалектом не владею. Как с помощью Top поизящней записать запрос нижеприведенному?
Код: plaintext
select sum(Значение) from Остатки where Начало<=:data and Конец > :data
Да такой запрос быстрее - согласен - на моих данных где-то в 1,5-2 раза. Странно тут то, что мне не приходилось за свою практику задумываться что такой подход:
Код: plaintext
select A....,SUM(Остаток(A.id,...)) from Номенклатура A group by ...
надо ускорять. Вроде никогда не было проблем с доступностью данных для аналитических отчетов.
При этом такой показатель как "операций в секунду" не страдает.

Кстати, хотел спросить про "отложенный" расчет отдельным потоком. Я так понимаю, существует лаг между записью фактического движения и "наличием" фактического остатка по учетной единице. Каким способом обеспечивалась "непротиворечивость" данных?, к примеру если алгоритму требуется величина остатка после записи движения, для следующей операции? Или было управление из алгоритма "можно отложить"/"нельзя отложить" расчет? И еще, например, у меня в расчете есть различные проверки на выход за разные пределы остатка и т.п., в большинстве случаев они являются критерием возможности проведения операции и этим проверкам нужен остаток. Если существует пул необработанных движений, как работают такие механизмы?
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35029593
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex SКстати, хотел спросить про "отложенный" расчет отдельным потоком. Я так понимаю, существует лаг между записью фактического движения и "наличием" фактического остатка по учетной единице. Каким способом обеспечивалась "непротиворечивость" данных?, к примеру если алгоритму требуется величина остатка после записи движения, для следующей операции? Или было управление из алгоритма "можно отложить"/"нельзя отложить" расчет? И еще, например, у меня в расчете есть различные проверки на выход за разные пределы остатка и т.п., в большинстве случаев они являются критерием возможности проведения операции и этим проверкам нужен остаток. Если существует пул необработанных движений, как работают такие механизмы?
Для всякой аналитики используются только "обработанные" движения - то есть работа идет с таблицей остатков. Ну а для проверок естественно надо учесть необработанные. Но тут хитрость в том, что необработанных движений крайне мало, поэтому дополнительный запрос считающий сумму необработанных движений работает быстро. То есть у нас есть два остатка - аналитический (время получения которого не зависит от количества движений) и оперативный (получение которого больше на время суммирования маленького списка неучтенных движений).
Сам пул необработанных движений можно организовать по-разному.
Первый способ - колонка в списке движений, принимающая значения 1 (необработано) и null (обработано) - индекс по такой колонке очень мал и поиск по нему осуществляется быстро.
Второй - складывать необработанные движения в отдельную таблицу (а после обработке оттуда удалять). Мы исползовали именно этот способ - так как хотелось минимизировать воздействие "отложенного" расчета на код системы (чтобы это было этаким дополнительным функционалом, устанавливаемым/убираемым по желанию).
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35032810
Alex S
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bogdanov AndreyДля всякой аналитики используются только "обработанные" движения - то есть работа идет с таблицей остатков. Ну а для проверок естественно надо учесть необработанные. Но тут хитрость в том, что необработанных движений крайне мало, поэтому дополнительный запрос считающий сумму необработанных движений работает быстро. То есть у нас есть два остатка - аналитический (время получения которого не зависит от количества движений) и оперативный (получение которого больше на время суммирования маленького списка неучтенных движений).
Сам пул необработанных движений можно организовать по-разному.
Первый способ - колонка в списке движений, принимающая значения 1 (необработано) и null (обработано) - индекс по такой колонке очень мал и поиск по нему осуществляется быстро.
Второй - складывать необработанные движения в отдельную таблицу (а после обработке оттуда удалять). Мы исползовали именно этот способ - так как хотелось минимизировать воздействие "отложенного" расчета на код системы (чтобы это было этаким дополнительным функционалом, устанавливаемым/убираемым по желанию). Спасибо за ответы. А в целом - реальные тесты показывали значительный/заметный/(другое) прирост производительности с пулом?
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35033045
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex S Спасибо за ответы. А в целом - реальные тесты показывали значительный/заметный/(другое) прирост производительности с пулом?
Да, в описанной выше ситуации: Bogdanov Andreyучетных единиц было мало (порядка сотни), а конкурирующих транзакций - много (до полусотни процессов и десятки тысяч операций в час у каждого).количество обрабатываемых транзакций возросло в несколько раз (раза в три-семь, точнее не скажу - не помню). Вполне вероятно, что итоговая схема не была оптимальной именно для этого случая, но это было решение полученное путем минимальных модификаций уже работавшей системы. И обеспечило простую поддежрку версии совместно с остальными.
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35035935
a7exander
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
хочу рассказать о своем методе расчета остатков на любую дату, несмотря на то что метод очень прост никто его почемуто не предложил.

сперва у нас использовалось тупое суммирование по указанную дату:
Код: plaintext
select SUM(quant),name from reestr where dat<:d group by name

но когда реестр дорос до 3млн записей стало подтормаживать.

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

1. если построен индекс по полю reestr.dat то любым способ добится того чтобы он НЕ ИСПОЛЬЗОВАЛСЯ в данном запросе, например так:
Код: plaintext
select SUM(quant),name from reestr where coalesce(dat,dat)<:d group by name
разницы на небольших таблицах заметно не будет, но на таблицах с миллионами строк у меня только одним этим удалось поднять скорость расчета в 50-100(!!!) раз. поскольку селективность индекса по dat очень высока оптимизатор запросов пытается использовать его в первую очередь. После такой оптимизации запрос на многомиллионной таблице стал отрабатывать вместо 15секунд 200миллисекунд.

2. если не хочется суммировать многие тысячи строк с начала времен то можно суммировать строки с конца!
для этого в реестр для каждого склада и каждой номенклатуры добавляется одна запись, которая будет содержать остаток на сейчас со знаком минус и датой движения для которой (reestr.dat) будет к примеру 01.01.2100 года. тогда получать остатки можно запросом
Код: plaintext
select SUM(quant),name from reestr where dat>=:d group by name
а строчку с остатками на сейчас поддерживать актуальной при помощи триггеров. И это при том что фактически возможность считать по этой же таблице старым методом НЕ ТЕРЯЕТСЯ, надо лишь только в запросах не забывать указывать по какую дату считать ;)

оба метода успешной мной эксплуатируются :)
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35036131
TORT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У нас похожий метод расчета... Только хранятся две вещи... Итоговый остаток по товарам, то есть сумма по всему движению... Ну и обсчитывается все движение от нужной даты... Строк в БД примерно 150 млн...
...
Рейтинг: 0 / 0
быстрое получение остатков на дату
    #35036220
Bogdanov Andrey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a7exander
1. если построен индекс по полю reestr.dat то любым способ добится того чтобы он НЕ ИСПОЛЬЗОВАЛСЯ в данном запросе, например так:
У Oracle оптимизатор, собака, умный, и индекс в таком случае и сам не всегда использует.

a7exanderдля этого в реестр для каждого склада и каждой номенклатуры добавляется одна запись, которая будет содержать остаток на сейчас со знаком минус
Ну если уж хранить остаток, то можно тогда не только на сейчас хранить, но и на промежуточные дату. Все равно на проблему с блокировками уже нарвались.
...
Рейтинг: 0 / 0
25 сообщений из 51, страница 2 из 3
Форумы / Сравнение СУБД [игнор отключен] [закрыт для гостей] / быстрое получение остатков на дату
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]