Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / задачка про историю... / 25 сообщений из 48, страница 1 из 2
30.03.2005, 01:24
    #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
30.03.2005, 02:01
    #32987544
ChA
ChA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
задачка про историю...
1. Сервер ?
2. Структура потенциально изменяема ?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Для этого в родительской таблице применить циклический счетчик по модулю 30 . Пока его значение меньше 30, запись вставляется. Далее делается Update в запись, значение ключа которой равно значению счетчика.
...
Рейтинг: 0 / 0
30.03.2005, 12:52
    #32988346
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
задачка про историю...
PVPНе добавлять и не удалять записи. Вместо этого применить Update. Особенно это добавит быстродействия, если в Update не попадут поля, используемые в индексах.
Насколько я понимаю, при любой нормальной реализации сервера UPDATE таки заметно медленнее INSERT. Соответственно, мысль хороша, но если скорость добавления не является абсолютно критичной.
...
Рейтинг: 0 / 0
30.03.2005, 13:02
    #32988369
PVP
PVP
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
задачка про историю...
softwarer PVPНе добавлять и не удалять записи. Вместо этого применить Update. Особенно это добавит быстродействия, если в Update не попадут поля, используемые в индексах.
Насколько я понимаю, при любой нормальной реализации сервера UPDATE таки заметно медленнее INSERT. Соответственно, мысль хороша, но если скорость добавления не является абсолютно критичной.Insert выполняет меньше работы с LOG-файлом. Но при этом обязательно требуется перестроение индексов. Если Размер записи не большой, то затраты на работу с LOG в оператора Update не значительные.
Кроме того, в контексте данного вопроса, если применять Insert, то придется применять Delete. А здесь уже полностью задействуется и LOG, и индексы.
По моему опыту, самые большие тормоза при вставке и уделении с больших таблицами - это индексы.
...
Рейтинг: 0 / 0
30.03.2005, 13:12
    #32988418
Jimmy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
задачка про историю...
А количество записей - принипиально?
Если исходить из предположения, что данное ограничение связано с экономией дискового пространства, то может задачу можно несколько видоизменить, например условие "количество записей" заменить на "записей за последние 30 дней" скажем?
Если так, то все будет гораздо проще. Иначе - "тяжелые" SQL запросы, о которых говорилось выше, или какие-нибудь трюки.
...
Рейтинг: 0 / 0
30.03.2005, 13:21
    #32988451
PVP
PVP
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
задачка про историю...
JimmyА количество записей - принипиально?
Если исходить из предположения, что данное ограничение связано с экономией дискового пространства, то может задачу можно несколько видоизменить, например условие "количество записей" заменить на "записей за последние 30 дней" скажем?
Если так, то все будет гораздо проще. Иначе - "тяжелые" SQL запросы, о которых говорилось выше, или какие-нибудь трюки.Если позволить накопление записей, то самая тяжелая часть SQL-запроса при удалении будет
"... from table_b inner join table_a on ...". А там же есть еще и "...Where ...". И сколько времени будет проходить удаление, можно только догадываться, а следовательно гадать "Пройдет до началы смены или нет?"
...
Рейтинг: 0 / 0
30.03.2005, 13:26
    #32988467
PVP
PVP
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
задачка про историю...
Я не знаю почему, но от количества записей в таблице время удаления записит нелинейно, по параболе. Для удаления больших массивов приходится использовать курсор, что бы он удалял записи кусками. Во первых, так проходит быстрее и, во-вторых, можно наблюдать прогресс удаления.
...
Рейтинг: 0 / 0
30.03.2005, 17:56
    #32989504
Programmer_Ortodox
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
задачка про историю...
Некогда вникать сильно в суть, то мне кажется, что если нужно удалять запись "master", и ее записи в "detail" в процессе работы и, счет идет на миллионы записей (юзеров скока будет законнекчено?), то система будет неработоспособна из-за низкой скорости. Напрашивается мысль о пометки записей как удаленных, а физически удалять в соотв. с придуманным регламентом.
...
Рейтинг: 0 / 0
30.03.2005, 18:23
    #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
30.03.2005, 18:30
    #32989602
PVP
PVP
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
задачка про историю...
2 Jimmy
Да, JOIN там действительно не зачем.
...
Рейтинг: 0 / 0
30.03.2005, 23:01
    #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
31.03.2005, 02:08
    #32989969
ChA
ChA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
задачка про историю...
папа Карлотак никто не удаляет.... ибо индексы не работают....
...
тьщательнее товарищи.... не допускаем тейблсканов..... ;)
Вообще-то деньги за эту работу платят вам, так что удаляйте как надо и не допускайте тейблсканов...
...
Рейтинг: 0 / 0
31.03.2005, 04:02
    #32989986
папа Карло
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
задачка про историю...
авторВообще-то деньги за эту работу платят вам, так что удаляйте как надо и не допускайте тейблсканов...

хороший солюшен. мне нравится :)
...
Рейтинг: 0 / 0
31.03.2005, 04:11
    #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]