powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / задачка про историю...
25 сообщений из 48, страница 1 из 2
задачка про историю...
    #32987530
папа Карло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица А в ней порядка 7ми миллионов записей. И таблица Б в которой скажем 500 миллионов записей. Таблица Б является дитем от таблицы А.

table_a
======
id <pk>
....

table_b
======
id <pk, fk> (FK to table_a.id)
date <pk>
.....

т.е. для каждого ИД из таблицы А я имею от нуля до N записей в таблице Б с разными датами.

т.е. таблица Б не что иное как "лог-файл". Задача проста.... для каждго ИД из таблицы А хранить не более скажем 30ти записей в таблице Б. Т.е. при добавлении новой записи с последней датой, старая (которая стала 31ой) должна уйти.... Желательно чтобы удаление производилось ночью и вставка новых записей не была сильно нагружена.

в день добавляется около 10 млн записей.... т.е. порядок удаления будет такой же.

ну кто тут самый главный архитектор? :)
...
Рейтинг: 0 / 0
задачка про историю...
    #32987544
Фотография ChA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Сервер ?
2. Структура потенциально изменяема ?

Решение 1
На уровне идеи, можно ничего вообще не удалять, а для каждого table_a.id сразу вставить 30 записей, а потом переписывать самые старые записи новой информацией, типа закольцованого буфера.

P.S. На главного архитектора не претендую, полагаю решений еще будет много.
...
Рейтинг: 0 / 0
задачка про историю...
    #32987559
папа Карло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
структура жесткая.... сразу создавать нельзя. это будет против правил бизнесса.
...
Рейтинг: 0 / 0
задачка про историю...
    #32987560
папа Карло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МС СКЛ если это играет роль.
...
Рейтинг: 0 / 0
задачка про историю...
    #32987566
c127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 папа Карло

>для каждго ИД из таблицы А хранить не более скажем 30ти записей в таблице Б.
....
Желательно чтобы удаление производилось ночью и вставка новых записей не была сильно нагружена.

Какое из правил может быть нарушено при попытке добавить 31-ю запись?

Если первое то решение - скрипт зпаускаемый ночью и удаляющий все кроме последних 30 записей. Вставка не загружена.

Если второе - то триггер или вставка через процедуру, но первое ИМХО лучше. Вставка загружена, но по-моему ничего другого, что бы точно поддерживало предел в 30 записей придумать невозможно.

ИМХО оптимизировать можно только запросы, которые будут это все выполнять плюс индексы.

Если есть желание то можем обсудить вопрос за пивом.
...
Рейтинг: 0 / 0
задачка про историю...
    #32987573
папа Карло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"и удаляющий все кроме последних 30 записей"

ты эту квери представил ? :) а теперь помножб на 7 млн..... а у меня только час есть на то, чтоб все почистить..... тут тоньше надо.
...
Рейтинг: 0 / 0
задачка про историю...
    #32987578
c127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
>ты эту квери представил ? :) а теперь помножб на 7 млн..... а у меня только час есть на то, чтоб все почистить..... тут тоньше надо.

Тоньше врядли получится. 7 млн за час может и отработает, если правильно проиндексировать. Это ~2000 записей/сек. Зависит от железа.

Можно триггером записывать количество дочерних записей во вспомогательное поле (или таблицу) и запросом бежать по записям, где кол-во дочерних больше 30. Но немного замедлится вставка.

По-моему удаление лишних записей во время вставки будет лучше.
...
Рейтинг: 0 / 0
задачка про историю...
    #32987580
папа Карло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я готов добавить оверхед на вставку.... но не сильный.... 2-3% не более. железо 4 камня, 4 гига.... раид 10.
...
Рейтинг: 0 / 0
задачка про историю...
    #32987593
c127
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
>я готов добавить оверхед на вставку.... но не сильный.... 2-3% не более. железо 4 камня, 4 гига.... раид 10.

Ты мне льстишь, я не такой спец по железу и МССКЛ-ю, чтоб глянуть и сразу сказать, уложится в час или нет. Если уложится, то впритык, но это чистое ИМХО.

Я бы сделал так. Написал бы триггер на вставку дочерней записи, который бы увеличивал на единицу поле-счетчик в родительской таблице, когда он больше 30, удалял бы самую старую запись. count не делать, хотя с ним было бы проще и надежней, но медленне. Хотя на 30 записях тяжело сказать, может и быстрее т.к. не нужно лазить в родительскую таблицу. Если вдруг будет быстро работать, то можно перейти на count. У тебя добваление ~120 записей в секунду, должно хватить. Понятно что еще нужно внимательно выставить isolation level.

Поле-счетчик можно вынести в отдельную таблицу и в другой tablespace, но это уже вариации на тему.
...
Рейтинг: 0 / 0
задачка про историю...
    #32987727
Фотография Old Nick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как выглядит индекс таблицы?

Если это primary key (FK, PK(Date))
то через count можно будет быстро почистить лишние записи, хоть разом хоть при вставке.

Если индекс другой, то и не знаю что можно предложить
...
Рейтинг: 0 / 0
задачка про историю...
    #32988017
sti
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
таблицы можно создавать дополнительно?
...
Рейтинг: 0 / 0
задачка про историю...
    #32988071
guest_20040621
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Imho две стратегии:

1. Удалять лишние записи при вставке новых. Плюс: компактность (хотя при оверхеде размера таблицы в 2% преимущество представляется сомнительным). Минус: увеличение времени добавления новых записей.

2. Удалять лишние записи периодически (необязательно ночью, количество запущенных экземпляров бота обратно пропорционально общей загруженности сервера). Оптимизировать просмотр записей table_a (например, добавлением date (время последней вставки данных в table_b, соответствующим table_a.id) для исключения полного перебора. Плюс: мало изменяется время добавления новых записей. Минус: изменяется структура таблицы; дополнительный код для оптимизатора бота.

1. проще, 2. imho правильнее.
...
Рейтинг: 0 / 0
задачка про историю...
    #32988300
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не добавлять и не удалять записи. Вместо этого применить Update. Особенно это добавит быстродействия, если в Update не попадут поля, используемые в индексах.

Для этого в родительской таблице применить циклический счетчик по модулю 30 . Пока его значение меньше 30, запись вставляется. Далее делается Update в запись, значение ключа которой равно значению счетчика.
...
Рейтинг: 0 / 0
задачка про историю...
    #32988346
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PVPНе добавлять и не удалять записи. Вместо этого применить Update. Особенно это добавит быстродействия, если в Update не попадут поля, используемые в индексах.
Насколько я понимаю, при любой нормальной реализации сервера UPDATE таки заметно медленнее INSERT. Соответственно, мысль хороша, но если скорость добавления не является абсолютно критичной.
...
Рейтинг: 0 / 0
задачка про историю...
    #32988369
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer PVPНе добавлять и не удалять записи. Вместо этого применить Update. Особенно это добавит быстродействия, если в Update не попадут поля, используемые в индексах.
Насколько я понимаю, при любой нормальной реализации сервера UPDATE таки заметно медленнее INSERT. Соответственно, мысль хороша, но если скорость добавления не является абсолютно критичной.Insert выполняет меньше работы с LOG-файлом. Но при этом обязательно требуется перестроение индексов. Если Размер записи не большой, то затраты на работу с LOG в оператора Update не значительные.
Кроме того, в контексте данного вопроса, если применять Insert, то придется применять Delete. А здесь уже полностью задействуется и LOG, и индексы.
По моему опыту, самые большие тормоза при вставке и уделении с больших таблицами - это индексы.
...
Рейтинг: 0 / 0
задачка про историю...
    #32988418
Фотография Jimmy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А количество записей - принипиально?
Если исходить из предположения, что данное ограничение связано с экономией дискового пространства, то может задачу можно несколько видоизменить, например условие "количество записей" заменить на "записей за последние 30 дней" скажем?
Если так, то все будет гораздо проще. Иначе - "тяжелые" SQL запросы, о которых говорилось выше, или какие-нибудь трюки.
...
Рейтинг: 0 / 0
задачка про историю...
    #32988451
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JimmyА количество записей - принипиально?
Если исходить из предположения, что данное ограничение связано с экономией дискового пространства, то может задачу можно несколько видоизменить, например условие "количество записей" заменить на "записей за последние 30 дней" скажем?
Если так, то все будет гораздо проще. Иначе - "тяжелые" SQL запросы, о которых говорилось выше, или какие-нибудь трюки.Если позволить накопление записей, то самая тяжелая часть SQL-запроса при удалении будет
"... from table_b inner join table_a on ...". А там же есть еще и "...Where ...". И сколько времени будет проходить удаление, можно только догадываться, а следовательно гадать "Пройдет до началы смены или нет?"
...
Рейтинг: 0 / 0
задачка про историю...
    #32988467
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я не знаю почему, но от количества записей в таблице время удаления записит нелинейно, по параболе. Для удаления больших массивов приходится использовать курсор, что бы он удалял записи кусками. Во первых, так проходит быстрее и, во-вторых, можно наблюдать прогресс удаления.
...
Рейтинг: 0 / 0
задачка про историю...
    #32989504
Programmer_Ortodox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Некогда вникать сильно в суть, то мне кажется, что если нужно удалять запись "master", и ее записи в "detail" в процессе работы и, счет идет на миллионы записей (юзеров скока будет законнекчено?), то система будет неработоспособна из-за низкой скорости. Напрашивается мысль о пометки записей как удаленных, а физически удалять в соотв. с придуманным регламентом.
...
Рейтинг: 0 / 0
задачка про историю...
    #32989581
Фотография Jimmy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PVPЕсли позволить накопление записей, то самая тяжелая часть SQL-запроса при удалении будет
"... from table_b inner join table_a on ...". А там же есть еще и "...Where ...". И сколько времени будет проходить удаление, можно только догадываться, а следовательно гадать "Пройдет до началы смены или нет?"

Не понял проблемы. В случае "записей за последние 30 дней":

-- for Sybase ASE 12.x
DELETE MyTable WHERE MyDate < convert(char(8),dateadd(dd,-30,getdate()),112)

Где там join?
...
Рейтинг: 0 / 0
задачка про историю...
    #32989602
Фотография PVP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Jimmy
Да, JOIN там действительно не зачем.
...
Рейтинг: 0 / 0
задачка про историю...
    #32989891
папа Карло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
за посл. 30 дней удаляем сейчас и как бы работает без проблем..... проблема в том, что по некоторым ИД записи в логе появляются скажем раз в год или два года, без системно, но далеко не каждый день, именно поэтому поступило требование хранить последние Н(30-40) обзоров.

апдейт не подходит совсем... дата (в виде инта) в индексе и никуда ты от нее не денешься... было бы интересно посмотреть на солюшен с пометкой записей которые надо удалить....

ну и между делом..... тут код привели....

Код: plaintext
DELETE MyTable WHERE MyDate < convert(char( 8 ),dateadd(dd,- 30 ,getdate()), 112 )

так никто не удаляет.... ибо индексы не работают.....

Код: plaintext
1.
2.
declare @border datetime
set @border = dateadd( d, - 30 , getdate())
delete from table where date <= @border

тьщательнее товарищи.... не допускаем тейблсканов..... ;)
...
Рейтинг: 0 / 0
задачка про историю...
    #32989969
Фотография ChA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
папа Карлотак никто не удаляет.... ибо индексы не работают....
...
тьщательнее товарищи.... не допускаем тейблсканов..... ;)
Вообще-то деньги за эту работу платят вам, так что удаляйте как надо и не допускайте тейблсканов...
...
Рейтинг: 0 / 0
задачка про историю...
    #32989986
папа Карло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВообще-то деньги за эту работу платят вам, так что удаляйте как надо и не допускайте тейблсканов...

хороший солюшен. мне нравится :)
...
Рейтинг: 0 / 0
задачка про историю...
    #32989988
Сонный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А можно мне как полному профану в MS SQL тоже попутно задать вопросик?

Что будет если перед добавлением записи делать так:
delete from table_b и
where b.id = @a_pk
and b.date not in
(select top 29 t.date from table_b t
where id = @a_pk
order by t.date desc)
?
Такой вариант чем плох?
...
Рейтинг: 0 / 0
25 сообщений из 48, страница 1 из 2
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / задачка про историю...
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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