|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
Коллеги, приветствую! Помогите решить очередную задачу. Имеется некая таблица. В ней хранятся текущие значения данных. Если производится апдейт записи, то информация о предыдущих значениях полей сваливается в некую историческую таблицу. Вообще то в EAV, но предлагаю не заниматься онанизмом, и считать, что pivot этой исторической таблицы - уже сделан. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45.
id a b c1 3 abc 2001-01-01 00:00:002 4 NULL 2002-01-01 00:00:00 id dt_change a b c1 2005-03-10 00:00:00 NULL d NULL1 2003-01-10 00:00:00 2 d 2001-01-03 00:00:001 2002-01-10 00:00:00 NULL NULL NULL1 2001-01-11 00:00:00 1 NULL NULL1 2001-01-10 00:00:00 NULL c 2001-01-01 00:00:002 2003-01-11 00:00:00 6 rr 2003-01-03 00:00:002 2002-01-20 00:00:00 NULL NULL NULL2 2001-01-15 00:00:00 1 NULL NULL В случае, если значение поля не поменялось с предыдущего раза, то в исторической таблице - NULL, если изменилось - то в историческую таблицу пишется предыдущее значение поля. Задача - восстановить значение записей на каждую дату. Т.е. для Ид = 1 на 2005-03-10 (эээ... до этой даты :-) ) значения будут: 1 3 d 2001-01-01 До 2003-01-01: 1 2 d 2001-01-03 До 2002-01-10: 1 2 d 2001-01-03 И т.д. Как размотать эту "историю" с минимумом телодвижений? В исходной таблице - примерно миллион записей (и около 200 полей), в исторической, уже отпивотированной - порядка 10 млн. записей. Хотелось бы, чтобы считалось сколько нибудь обозримое время. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.11.2021, 20:45 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
uaggster В исходной таблице - примерно миллион записей (и около 200 полей), в исторической, уже отпивотированной - порядка 10 млн. записей. не надо ничего пивотить 200 outer apply-ев типа Код: sql 1.
и все дела ! ) ... нуу и индекс "правильный" на tbl_history, конечно ... |
|||
:
Нравится:
Не нравится:
|
|||
19.11.2021, 08:38 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
court, быстродействие будет чудовищным. Мне бы так, чтобы хоть за пару часов посчиталось. В оригинальной EAV таблице - под 500 млн. записей. В рамках такой постановки не получится что-то сделать? Я не знаю, рекурсию что-ли прикрутить... ... |
|||
:
Нравится:
Не нравится:
|
|||
19.11.2021, 15:23 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
uaggster, я бы курсором накатил и спал спокойно. 10 млн вставок многовато, но обозримо. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.11.2021, 15:57 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
uaggster, В подобной задаче выбирал данные из источника с сортировкой по ключевым полям и дате (соотв. оптимизация запроса), вставляя по условию сохраненное поле предыдущей строки скриптом SSIS. Вкупе с пакетной вставкой это отработает очень быстро. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.11.2021, 16:33 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
А в сторону temporal table не смотрели? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.11.2021, 16:56 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
uaggster Как размотать эту "историю" с минимумом телодвижений? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
uaggster Хотелось бы, чтобы считалось сколько нибудь обозримое время. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.11.2021, 22:07 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
msLex А в сторону temporal table не смотрели? Надо же, EAV... Ну, первое в жизни логирование все делают EAV, чужой опыт тут бессилен :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.11.2021, 22:09 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
uaggster, авторсваливается в некую историческую таблицу. Вообще то в EAV На самом деле выгодно хранить историю в виде полных строк, а EAV формировать на лету. EAV сложно обрабатывать средствами T-SQL, особенно, если количество строк от 100кк и выше. Поэтому надо восстановить полные строки в таблице по такой истории один раз и пополнять эту таблицу. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.11.2021, 22:13 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
Коллеги мопед не мой, да и гараж - тоже. Я только занимаюсь ... как будет правильно по-русски... ассенизацией данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.11.2021, 17:53 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
.Евгений uaggster, В подобной задаче выбирал данные из источника с сортировкой по ключевым полям и дате (соотв. оптимизация запроса), вставляя по условию сохраненное поле предыдущей строки скриптом SSIS. Вкупе с пакетной вставкой это отработает очень быстро. Будет балк, и миллиарды строк не будут проблемой. Если срок десяток миллионов, то можно сделать курсором. Ну или ждать, когда в сиквеле допилят lag для not null :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.11.2021, 18:28 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
alexeyvg, через потоки это тоже самое, что я писал: "я бы курсором накатил и спал спокойно". Но вставка будет быстрее, согласен. 2 uaggster: если непонятно, о чем я писал. Для каждого поля надо создать переменную, все переменные имеют начальное значение null. Читаем из потока первую строку и находим результат переменная = isnull(переменная, полученное_значение). Если получили null, то в результирующую таблицу отправляется прежнее значение переменной, иначе новое значение поля. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 01:04 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
Получилось вот что: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76.
Правда, меня пугает вставка 10 млн. строк по одной... Надо подумать как это либо пакетировать, либо, я не знаю, отложенную стабильность, что-ли, вглючить... ... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 10:23 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
Владислав Колосов, на всех этапах это будет быстрее. И чтение селекта (вместо курсора), и трансформация C# (вместо SQL), и вставка. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 10:47 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 10:55 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
Владислав Колосов через потоки это тоже самое, что я писал: "я бы курсором накатил и спал спокойно". Но вставка будет быстрее, согласен. Для чтения само собой, так чтение всегда чтение, чего там. Всё равно надо как минимум один раз прочитать таблицу с сотрировкой. А вот для записи разница огромная, сделать миллиард инсёртов, или один раз балк инсёрт миллиарда записей... ... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 14:05 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
uaggster, Странная система ниппель с храненем исторических данных. Лучше сделайте якорную модель -- история по каждому аттрибуту отдельно. А TEMPORAL заюзать версия не позволяет? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 15:18 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
a_voronin uaggster, Странная система ниппель с храненем исторических данных. Лучше сделайте якорную модель -- история по каждому аттрибуту отдельно. А TEMPORAL заюзать версия не позволяет? Да не мой это мопед, даже близко. Я вытаскиваю данные из работающей системы, чтобы передать их в перспективную. Там чёрт ногу сломит, как обычно. Что хранится, где хранится, как соотносится с бизнес-процессом. Полный Пэ. Т.к. весь этот перенос в новую систему еще многократно будет перепроверяться бизнесом, с т.з. правильности конвертации - эта задача не однократная (но и не постоянная, т.к. за n итераций - должна кончиться). Поэтому быстродействие, в принципе, волнует. Но не так, чтобы очень. Я ж говорю - это больше работа ассенизатора. Ну вот, попалась вот такая "система ниппель". Чего сделаешь то? ниппель-не ниппель, а говно качать надо. invm , не алле. Запрос неверный. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 17:04 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
uaggster, чужой мопед не трожь! Собери свой. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 17:10 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
Наверное, курсором обойдусь. Там, правда, не 10 млн, а 30 млн записей :-( Думаю in memory table сделать буферную, тысяч на 10 записей, писать в нее по одной записи, а потом делать из нее select в целевую. Будет быстрее? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 17:20 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
uaggster, упс... перепутал тему ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 17:46 |
|
Как "отмотать" историю?
|
|||
---|---|---|---|
#18+
uaggster Наверное, курсором обойдусь. Там, правда, не 10 млн, а 30 млн записей :-( Думаю in memory table сделать буферную, тысяч на 10 записей, писать в нее по одной записи, а потом делать из нее select в целевую. Будет быстрее? Но вы всё таки подумайте о SSIS Там можно будет прямо с EAV данные брать, получится быстро. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.11.2021, 20:48 |
|
|
start [/forum/topic.php?fid=46&fpage=9&tid=1684085]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
30ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
2ms |
others: | 13ms |
total: | 136ms |
0 / 0 |