Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
Есть таблица А в ней порядка 7ми миллионов записей. И таблица Б в которой скажем 500 миллионов записей. Таблица Б является дитем от таблицы А. table_a ====== id <pk> .... table_b ====== id <pk, fk> (FK to table_a.id) date <pk> ..... т.е. для каждого ИД из таблицы А я имею от нуля до N записей в таблице Б с разными датами. т.е. таблица Б не что иное как "лог-файл". Задача проста.... для каждго ИД из таблицы А хранить не более скажем 30ти записей в таблице Б. Т.е. при добавлении новой записи с последней датой, старая (которая стала 31ой) должна уйти.... Желательно чтобы удаление производилось ночью и вставка новых записей не была сильно нагружена. в день добавляется около 10 млн записей.... т.е. порядок удаления будет такой же. ну кто тут самый главный архитектор? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 01:24 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
1. Сервер ? 2. Структура потенциально изменяема ? Решение 1 На уровне идеи, можно ничего вообще не удалять, а для каждого table_a.id сразу вставить 30 записей, а потом переписывать самые старые записи новой информацией, типа закольцованого буфера. P.S. На главного архитектора не претендую, полагаю решений еще будет много. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 02:01 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
структура жесткая.... сразу создавать нельзя. это будет против правил бизнесса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 02:37 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
МС СКЛ если это играет роль. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 02:37 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
2 папа Карло >для каждго ИД из таблицы А хранить не более скажем 30ти записей в таблице Б. .... Желательно чтобы удаление производилось ночью и вставка новых записей не была сильно нагружена. Какое из правил может быть нарушено при попытке добавить 31-ю запись? Если первое то решение - скрипт зпаускаемый ночью и удаляющий все кроме последних 30 записей. Вставка не загружена. Если второе - то триггер или вставка через процедуру, но первое ИМХО лучше. Вставка загружена, но по-моему ничего другого, что бы точно поддерживало предел в 30 записей придумать невозможно. ИМХО оптимизировать можно только запросы, которые будут это все выполнять плюс индексы. Если есть желание то можем обсудить вопрос за пивом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 03:15 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
"и удаляющий все кроме последних 30 записей" ты эту квери представил ? :) а теперь помножб на 7 млн..... а у меня только час есть на то, чтоб все почистить..... тут тоньше надо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 03:39 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
>ты эту квери представил ? :) а теперь помножб на 7 млн..... а у меня только час есть на то, чтоб все почистить..... тут тоньше надо. Тоньше врядли получится. 7 млн за час может и отработает, если правильно проиндексировать. Это ~2000 записей/сек. Зависит от железа. Можно триггером записывать количество дочерних записей во вспомогательное поле (или таблицу) и запросом бежать по записям, где кол-во дочерних больше 30. Но немного замедлится вставка. По-моему удаление лишних записей во время вставки будет лучше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 04:55 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
я готов добавить оверхед на вставку.... но не сильный.... 2-3% не более. железо 4 камня, 4 гига.... раид 10. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 05:02 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
>я готов добавить оверхед на вставку.... но не сильный.... 2-3% не более. железо 4 камня, 4 гига.... раид 10. Ты мне льстишь, я не такой спец по железу и МССКЛ-ю, чтоб глянуть и сразу сказать, уложится в час или нет. Если уложится, то впритык, но это чистое ИМХО. Я бы сделал так. Написал бы триггер на вставку дочерней записи, который бы увеличивал на единицу поле-счетчик в родительской таблице, когда он больше 30, удалял бы самую старую запись. count не делать, хотя с ним было бы проще и надежней, но медленне. Хотя на 30 записях тяжело сказать, может и быстрее т.к. не нужно лазить в родительскую таблицу. Если вдруг будет быстро работать, то можно перейти на count. У тебя добваление ~120 записей в секунду, должно хватить. Понятно что еще нужно внимательно выставить isolation level. Поле-счетчик можно вынести в отдельную таблицу и в другой tablespace, но это уже вариации на тему. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 06:26 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
Как выглядит индекс таблицы? Если это primary key (FK, PK(Date)) то через count можно будет быстро почистить лишние записи, хоть разом хоть при вставке. Если индекс другой, то и не знаю что можно предложить ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 09:08 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
таблицы можно создавать дополнительно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 11:01 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
Imho две стратегии: 1. Удалять лишние записи при вставке новых. Плюс: компактность (хотя при оверхеде размера таблицы в 2% преимущество представляется сомнительным). Минус: увеличение времени добавления новых записей. 2. Удалять лишние записи периодически (необязательно ночью, количество запущенных экземпляров бота обратно пропорционально общей загруженности сервера). Оптимизировать просмотр записей table_a (например, добавлением date (время последней вставки данных в table_b, соответствующим table_a.id) для исключения полного перебора. Плюс: мало изменяется время добавления новых записей. Минус: изменяется структура таблицы; дополнительный код для оптимизатора бота. 1. проще, 2. imho правильнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 11:23 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
Не добавлять и не удалять записи. Вместо этого применить Update. Особенно это добавит быстродействия, если в Update не попадут поля, используемые в индексах. Для этого в родительской таблице применить циклический счетчик по модулю 30 . Пока его значение меньше 30, запись вставляется. Далее делается Update в запись, значение ключа которой равно значению счетчика. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 12:38 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
PVPНе добавлять и не удалять записи. Вместо этого применить Update. Особенно это добавит быстродействия, если в Update не попадут поля, используемые в индексах. Насколько я понимаю, при любой нормальной реализации сервера UPDATE таки заметно медленнее INSERT. Соответственно, мысль хороша, но если скорость добавления не является абсолютно критичной. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 12:52 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
softwarer PVPНе добавлять и не удалять записи. Вместо этого применить Update. Особенно это добавит быстродействия, если в Update не попадут поля, используемые в индексах. Насколько я понимаю, при любой нормальной реализации сервера UPDATE таки заметно медленнее INSERT. Соответственно, мысль хороша, но если скорость добавления не является абсолютно критичной.Insert выполняет меньше работы с LOG-файлом. Но при этом обязательно требуется перестроение индексов. Если Размер записи не большой, то затраты на работу с LOG в оператора Update не значительные. Кроме того, в контексте данного вопроса, если применять Insert, то придется применять Delete. А здесь уже полностью задействуется и LOG, и индексы. По моему опыту, самые большие тормоза при вставке и уделении с больших таблицами - это индексы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 13:02 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
А количество записей - принипиально? Если исходить из предположения, что данное ограничение связано с экономией дискового пространства, то может задачу можно несколько видоизменить, например условие "количество записей" заменить на "записей за последние 30 дней" скажем? Если так, то все будет гораздо проще. Иначе - "тяжелые" SQL запросы, о которых говорилось выше, или какие-нибудь трюки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 13:12 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
JimmyА количество записей - принипиально? Если исходить из предположения, что данное ограничение связано с экономией дискового пространства, то может задачу можно несколько видоизменить, например условие "количество записей" заменить на "записей за последние 30 дней" скажем? Если так, то все будет гораздо проще. Иначе - "тяжелые" SQL запросы, о которых говорилось выше, или какие-нибудь трюки.Если позволить накопление записей, то самая тяжелая часть SQL-запроса при удалении будет "... from table_b inner join table_a on ...". А там же есть еще и "...Where ...". И сколько времени будет проходить удаление, можно только догадываться, а следовательно гадать "Пройдет до началы смены или нет?" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 13:21 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
Я не знаю почему, но от количества записей в таблице время удаления записит нелинейно, по параболе. Для удаления больших массивов приходится использовать курсор, что бы он удалял записи кусками. Во первых, так проходит быстрее и, во-вторых, можно наблюдать прогресс удаления. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 13:26 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
Некогда вникать сильно в суть, то мне кажется, что если нужно удалять запись "master", и ее записи в "detail" в процессе работы и, счет идет на миллионы записей (юзеров скока будет законнекчено?), то система будет неработоспособна из-за низкой скорости. Напрашивается мысль о пометки записей как удаленных, а физически удалять в соотв. с придуманным регламентом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 17:56 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
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? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 18:23 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
2 Jimmy Да, JOIN там действительно не зачем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 18:30 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
за посл. 30 дней удаляем сейчас и как бы работает без проблем..... проблема в том, что по некоторым ИД записи в логе появляются скажем раз в год или два года, без системно, но далеко не каждый день, именно поэтому поступило требование хранить последние Н(30-40) обзоров. апдейт не подходит совсем... дата (в виде инта) в индексе и никуда ты от нее не денешься... было бы интересно посмотреть на солюшен с пометкой записей которые надо удалить.... ну и между делом..... тут код привели.... Код: plaintext так никто не удаляет.... ибо индексы не работают..... Код: plaintext 1. 2. тьщательнее товарищи.... не допускаем тейблсканов..... ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.03.2005, 23:01 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
папа Карлотак никто не удаляет.... ибо индексы не работают.... ... тьщательнее товарищи.... не допускаем тейблсканов..... ;) Вообще-то деньги за эту работу платят вам, так что удаляйте как надо и не допускайте тейблсканов... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2005, 02:08 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
авторВообще-то деньги за эту работу платят вам, так что удаляйте как надо и не допускайте тейблсканов... хороший солюшен. мне нравится :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2005, 04:02 |
|
||
|
задачка про историю...
|
|||
|---|---|---|---|
|
#18+
А можно мне как полному профану в 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) ? Такой вариант чем плох? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.03.2005, 04:11 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=32987544&tid=1545940]: |
0ms |
get settings: |
11ms |
get forum list: |
18ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
88ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
84ms |
get tp. blocked users: |
2ms |
| others: | 276ms |
| total: | 501ms |

| 0 / 0 |
