Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Есть в бухучете всякая отчетность, которая требует печать "даты последнего движения". Встал вопрос оптимизации алгоритма расчета этой самой даты. Самое интересное, что ничего путного сделать не получилось! Тривиальный запрос типа Код: plaintext приводит к сканированию таблицы оборотов / проводок (кому как приятнее - вопрос достаточно абстрактный). И это понятно - я про сканирование всей таблицы. По счету могло вообще не быть движения, а могло быть движение вчера. Соответственно, никаких критериев по ограничению мощности выборки нет. Да, есть мифическое условие "Date < @Date", но чем дальше живет система, тем чаще строят такие отчеты за последние дни, так что этим условием можно как бы и пренебречь. Самое неприятное, что отчет могут попросить за любую дату... То есть хранить эту самую дату вместо со счетом не получится - тогда придется хранить эту дату для каждого счета за каждую дату, что немало вроде бы как. Есть, конечно, рабочая версия - строить "опорные" таблицы дат последнего движения. Скажем, раз в год или раз в квартал, это не суть важно. Важно, что такие "опорные" таблицы существенно улучшат выполнение запроса за счет того, что будут ограничивать выборку. Но это все как-то некузяво... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.01.2005, 22:20 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
А что, по всем AccountId сразу нужны данные? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 00:24 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
CrimeanЕсть в бухучете всякая отчетность, которая требует печать "даты последнего движения". Встал вопрос оптимизации алгоритма расчета этой самой даты. Самое интересное, что ничего путного сделать не получилось! Тривиальный запрос типа Код: plaintext приводит к сканированию таблицы оборотов / проводок (кому как приятнее - вопрос достаточно абстрактный). И это понятно - я про сканирование всей таблицы. По счету могло вообще не быть движения, а могло быть движение вчера. Соответственно, никаких критериев по ограничению мощности выборки нет. Да, есть мифическое условие "Date < @Date", но чем дальше живет система, тем чаще строят такие отчеты за последние дни, так что этим условием можно как бы и пренебречь. Самое неприятное, что отчет могут попросить за любую дату... То есть хранить эту самую дату вместо со счетом не получится - тогда придется хранить эту дату для каждого счета за каждую дату, что немало вроде бы как. Есть, конечно, рабочая версия - строить "опорные" таблицы дат последнего движения. Скажем, раз в год или раз в квартал, это не суть важно. Важно, что такие "опорные" таблицы существенно улучшат выполнение запроса за счет того, что будут ограничивать выборку. Но это все как-то некузяво... Лет 15 назад сделали вспомогательную таблицу timeStamp-index -все вводимые-удаляемые записи синхронно отражаются в этой таблице. Очень помогает - например связать репликациями разные базы данных или Ваш вариант запроса - мгновенный ответ. Ресурсов ест мало - хранится только штамп и индекс. Считаем это обязательно должно быть в любой вводимой руками базе. Правда - работаем с древовидной базой данных - а не с реляционной. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 08:55 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
CrimeanЕсть в бухучете всякая отчетность, которая требует печать "даты последнего движения". Встал вопрос оптимизации алгоритма расчета этой самой даты. Самое интересное, что ничего путного сделать не получилось! Тривиальный запрос типа Код: plaintext приводит к сканированию таблицы оборотов / проводок (кому как приятнее - вопрос достаточно абстрактный). И это понятно - я про сканирование всей таблицы. По счету могло вообще не быть движения, а могло быть движение вчера. Соответственно, никаких критериев по ограничению мощности выборки нет. Да, есть мифическое условие "Date < @Date", но чем дальше живет система, тем чаще строят такие отчеты за последние дни, так что этим условием можно как бы и пренебречь. Самое неприятное, что отчет могут попросить за любую дату... То есть хранить эту самую дату вместо со счетом не получится - тогда придется хранить эту дату для каждого счета за каждую дату, что немало вроде бы как. Есть, конечно, рабочая версия - строить "опорные" таблицы дат последнего движения. Скажем, раз в год или раз в квартал, это не суть важно. Важно, что такие "опорные" таблицы существенно улучшат выполнение запроса за счет того, что будут ограничивать выборку. Но это все как-то некузяво... Я, конечно, не доктор, но у Вас индексы по номеру счета и по дате построены? Как-то неловко даже спрашивать - но если индексы помещаются в RAM сервера то должно быть пофигу какого размера таблица проводок. Или у вас сотни тысяч субсчетов?.. Использование же журнала работы по сути мало отличается от обсчета таблицы проводок, т.к. количество записей имеет один порядок. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 10:11 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
[quot Crimean] Код: plaintext quot] Чегой-то такой запрос сервер посылает... требует чего-нибуть вроде Код: plaintext В этом случае могет помочь индекс (Date, AccountId). Сканироваться будет индекс и только в части Date < @Date. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 10:43 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Данные нужны, конечно, не по всем счетам - есть и закрытые и бездействующие и технические. Скажем так, данные нужны по 1/3 ... 1/2 счетов. TimeStamp есть, а толку? Как он поможет выичслить дату последнего движения? Да еще и на любую дату? Индексы есть все возможные и невозможные. Для определенности - кластерный по счету и некластерный по дате. Попытки насоздавать кучу покрывающих индексов по всем возможным комбинациям полей картину с приведенным запросом не изменили (да и не могли). Конечно GROUP BY, сорри, заработался, но сути дела это не меняет :) aleks2Сканироваться будет индекс и только в части Date < @Date Безусловно! Но все же (извините за самоцитирование) CrimeanДа, есть мифическое условие "Date < @Date", но чем дальше живет система, тем чаще строят такие отчеты за последние дни, так что этим условием можно как бы и пренебречь То есть, это условие, конечно, работает. Но - отсекает один - два дня, что на фоне 10 - 15 лет мало помогает :) В аналогичной ситуации с остатками перешли на хранение остатков по счетам за те дни, когда были остатки или обороты. Это существенно помогло. Правда, отожрав место. Ну и пришлось построить механизм контроля актуальности и пересчета по запросу. Но, как показала практика, оно того стоило. Работа, все же, чаще идет последними несколькими днями. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 11:03 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Тоже интересный случай: По валютным счетам - переоценка может идти хоть каждый день, а на самом деле движение по счету было пол года назад. У нас пока мы с Диасофта на свою систему не перешли с этим постоянно были проблемы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 11:15 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
2 gardenman А сейчас куда проблема делась? Или таки за каждый день храните? Или не паритесь затратами на расчет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 11:22 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
А если строить/достраивать раз в день отдельную таблицу типа: AccountId,Date (smalldatetime) кластерный индекс. Достройка займет пару минут ночью. Можно достраивать триггером (по вкусу). ИМХО, не будет тормозить даже через 10лет. В конце концов эти цифры не нужны за 10лет. Можно и резать :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 11:27 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
gardenmanТоже интересный случай: По валютным счетам - переоценка может идти хоть каждый день, а на самом деле движение по счету было пол года назад. У нас пока мы с Диасофта на свою систему не перешли с этим постоянно были проблемы. А в чем, собственно, проблема, все равно нужно иметь валютные остатки (хранить их или считать на лету - неважно. Переоценка выполняется проводками. Они Вам что, мешают? Они ведь не проходят по аналитической ведомости, выведенной в валюте счета. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 11:29 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
ой, не хочу все описывать заново поищите по форуму. Топик назывался "Литература" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 11:30 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Мдя. 5 страниц выдает в результате поиска по слову "Литература", но ничего, корелирующего с данным топиком, не нашел. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 13:35 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
CrimeanМдя. 5 страниц выдает в результате поиска по слову "Литература", но ничего, корелирующего с данным топиком, не нашел. Это мифический топик. Попросите администраторов поискать, мне тоже интересно. До сих пор про мультивалютный учет я ничего умного не увидел, разнообразные доморощенные решения без стройного логического описания :)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 13:48 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Про мультивалютный учет - предлагаю завести отдельный топик :) И в этом топике считать оффтопиком :) У меня вполне технический вопрос - как не аргерировать всю таблицу. Вариант с хранением не катит - очень дорого в хранении. Пока рабочих (и работающих) вариантов немного - или существенное ограничение количества счетов в отчете или хренение "срезов" дат последнего движения хотя бы несколько штук за год. Скажем, раз в месяц. Это немного даже для 10 лет (всего ~ 40 * количество счетов, это терпимо), а определенный выигрышь дает, скажем, срез на начало года (я понимаю, прошел всего месяц) прозволят сократить затраты с 4203 CPU 49171 Reads при 16.7 секундах (много!) до 1985 CPU 5261 Reads при 5.6 секундах (все равно много!) Что уже вполне неплохо. Подозреваю, что можно еще как-нить это упростить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 14:04 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
/topic/102032&hl= /topic/103177&hl=#770153 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 14:04 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
gardenman/topic/102032&hl= /topic/103177&hl=#770153 Искренне советую найти валютного бухгалтера или кассира банка и расспросить его о практике валютного учета. Из первых рук, ткскзть. Можно, конечно, почитать означенные топики. В один я дописал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 14:16 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
2 gardenman И что в этих топиках поможет "оптимизации алгоритма расчета этой самой даты"? Про мультивалютность и про основы учета я не спрашивал. Как бы не факт, что мой вопрос вообще про бухучет. Просто похожая задача. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.01.2005, 14:46 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Ну насчет отсутствия пользы индексов: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 10:19 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Пардон, неверно переписал WHERE (Data > @Date) следует читать WHERE (Data < @Date) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 10:25 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
2 aleks2 Если бы вопрос был техническим - он был бы задан в профильной конференции :) Все возможные и невозможные индексы есть. Объемы слегка не те. Счетов ~полмиллиона, оборотов ~ 10 миллионов. За менее чем 10 лет. Распределение неравномерное - с увеличением даты количество оборотов в день растет. Важна не конкретная выборка, важен принцип. В указанном запросе невозможно в принципе избавиться от сканирования всей таблицы сначала до указанной даты. Я ищу способ ДЕШЕВО от такого сканирования избавиться. Пока - теоретический. Рабочие варианты я указал. Они дают определенный выигрышь, но есть подозрение, что не вижу чего-то очевидного. Для этого и спрашиваю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 11:10 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Crimean2 aleks2 Если бы вопрос был техническим - он был бы задан в профильной конференции :) Все возможные и невозможные индексы есть. Объемы слегка не те. Счетов ~полмиллиона, оборотов ~ 10 миллионов. За менее чем 10 лет. Распределение неравномерное - с увеличением даты количество оборотов в день растет. Важна не конкретная выборка, важен принцип. В указанном запросе невозможно в принципе избавиться от сканирования всей таблицы сначала до указанной даты. Я ищу способ ДЕШЕВО от такого сканирования избавиться. Пока - теоретический. Рабочие варианты я указал. Они дают определенный выигрышь, но есть подозрение, что не вижу чего-то очевидного. Для этого и спрашиваю. Вообще начинают терзать смутные сомнения, что это нужно. Что за база у Вас такая? Она ведь явно не используется в оперативной работе, а отчета можно и подождать. Слуушайте, а Вы не связаны с госорганами - с украинской налоговой, например? Я помню когда была там тема про ИНН или что-то вроде него, я прикидывал в уме потребный объем/стоимость железа для обработки данных, которые они собрать хотели. Мне смешно было. Может, НЕ НУЖНА такая база и Вы решаете проблемы, которые на другом уровне надо было решать? Например, работать на местах с базами меньшего размера? Мне вот интересно, сеть Walmart (могу ошибаться) накапливает чуть не терабайты данных в день (о розничных продажах), так они тоже это обсчитывают в онлайн или как ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 13:28 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
2 Dogen Вопрос как раз в минимизации времени "подождать". Или смысл проблемы до сих пор остался неясным? Со временем будет неконтролируемый рост времени расчета, от чего хочется уйти. Ну и то, что Вас терзают смутные сомнения в необходимости никак не уберет эту самую необходимость. Она вполне себе материальна :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 13:35 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Для частого поиска последней операции можно создать специальный индекс с сортировкой по убыванию CREATE INDEX IX_OPR1_REW ON dbo.OPR1(DateOpr DESC, NomOpr DESC ) затем использовать оператор -- просто последняя операция Select top 1 NomOpr from Opr1 with (index(Ix_Opr1_Rew)) order by DateOpr Desc -- последняя до заданного события, например в текущем месяце Select top 1 NomOpr from Opr1 with (index(Ix_Opr1_Rew)) where DateOpr<'31.12.04' order by DateOpr Desc Выборка происходит мгновенно не зависимо от размера таблицы ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 19:14 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
2 PVP А для ВСЕХ операций? Для ОДНОЙ я и сам могу. Для всех - да, как-то неочевидно получилось, что отчет строится по ВСЕМ счетам или по бОльшей их части. В определении этой самой даты для одного счета проблем нет никаких совершенно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 19:18 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Crimean2 Dogen Вопрос как раз в минимизации времени "подождать". Или смысл проблемы до сих пор остался неясным? Со временем будет неконтролируемый рост времени расчета, от чего хочется уйти. Ну и то, что Вас терзают смутные сомнения в необходимости никак не уберет эту самую необходимость. Она вполне себе материальна :) Как это неконтролируемый? Будет типа какой-нибудь логарифм от количества документов (пущай грамотные товарищи поправют). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 19:24 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
DogenКак это неконтролируемый? Будет типа какой-нибудь логарифм от количества документов (пущай грамотные товарищи поправют). Логарифм он и есть логарифм. И результат логарифма уж точно неконтролируемый - он предопределенный законами природы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 19:45 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
А может построить отдельную таблицу, в которую переносить только уникальные значения пар AccountId и Date? Т.е. множество проводок по одному счету в один день породят в такой таблице только одну запись. Не уверен, что это отличается от использования композитных индексов, но в такой таблице в любом разе легче будет задействовать кластеризацию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 19:53 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
авторА может построить отдельную таблицу И чего? Будет сканиться она. Получим неконтролируемый рост / количество записей в день = неконтролируемый рост. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 20:05 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
-- Если есть разные счета, тогда надо использовать код операции CREATE INDEX IX_OPR1_REW ON dbo.OPR1(KofOpr, DateOpr DESC, NomOpr DESC ) -- Использовать временную таблиицу или таблицу памяти Declare @DateN DateTime, @DateK DateTime Create table #T (KodOPr int, DateOpr DateTime, NomOpr int) Insert into #T (KodOpr) select Distinct KodOpr from Opr1 with (index(Ix_Opr1_Rew)) where DateOpr between @DateN and @DateK -- Здесь нет перебора по базе, используется только индекс -- Заполнить таблицу последней датой Update t Set DateOpr=(select top 1 DateOpr from Opr1 with (index(Ix_Opr1_Rew)) order by DateOpr Desc, NomOpr desc), NomOpr=(select top 1 DateOpr from Opr1 with (index(Ix_Opr1_Rew)) order by DateOpr Desc, NomOpr desc) from #T t -- Можно еще уменьшить время в два раза, если помудрить -- над последним операторм, т.е. Declare @Str VarChar (50) Update t Set @Str =(select top 1 Convert(Char(15),DateOpr,4)+ Convert(Char(10), NomOpr) from Opr1 with (index(Ix_Opr1_Rew)) order by DateOpr Desc, NomOpr desc), DateOpr=Convert(DateTime,Left(@Str,15)), NomOpr=Convert(Int,Substring(@Str,16,10)) from #T t ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.01.2005, 20:16 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
2 PVP Спасибо! И ведь знал же про этот прием... Избавил от кучи лишней работы. Reads, конечно, в результате бы революционно уменьшилось, но так (через спекуляцию с индексом) все будет работать уже сейчас и без изменения системы. P.S.В "моем" случае и DESC индекса не понадобилось по своим причинам. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2005, 11:45 |
|
||
|
Дата последнего движения
|
|||
|---|---|---|---|
|
#18+
Crimean Обычно кроме проводок есть еще и закэшированная информация об остатках на счете При чем если ее делать по уму то эта таблица, грубо говоря, хранит записи только за те даты на которые по указанному счету были обороты. Ясно, что количество записей в такой таблице на порядок меньше чем в таблице проводок. Возможно, стоит требуемую информацию брать оттуда? Это что касается программной оптимизации - кроме того, у большинства СУБД есть свои средства работы с большими таблицами (тот же partitioned views) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.01.2005, 15:05 |
|
||
|
|

start [/forum/topic.php?all=1&fid=32&tid=1546081]: |
0ms |
get settings: |
8ms |
get forum list: |
17ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
42ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
69ms |
get tp. blocked users: |
1ms |
| others: | 262ms |
| total: | 415ms |

| 0 / 0 |
