|
|
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Данная тема также размещена в форуме Проектирование БД. сорри. Есть система под Oracle с более 300 клиентами. В данный момент система не устраивает по некоторым требования и принято решение о переписывании всего с нуля. Требуется разработать структуру БД для реализации под Oracle и Interbase (для установки на объекты с меньшим количеством пользователей и интенсивностью запросов). Есть основная таблица, в которой много полей, основные - Идентификатор и Состояние. Добавление записей в эту таблицу - 10 тыщ в день. У каждой добавленной записи поле Состояние почти последовательно проходит значения от 1 до 10. После достижения значения 10 запись становится архивной - поля не меняются. Сегодняшняя реализация: Все клиенты раз в 15 секунд делают выборку из этой таблицы с условием Состояние = Некоторой_константе, эта константа определяет тип приложения. Т.е. разные клиентские места выбирают записи с определенным состоянием и производят дальнейшую их обработку, меняя Состояние, тем самым передавая данную запись другим клиентам. В сегодняшней реализации из-за большой загрузки сервера (доходит почти до 100%) сделано архивирование данных - объекты с Состоянием = 10 переносятся в другую таблицу. Через месяц еще в одну - для статистики. Все 3 таблицы имеют одинаковую структуру. Обрабатывать 3 таблицы конечно не удобно, сделаны view`шки объединяющие все 3 таблицы и т.д. Разработчиками были приняты следущие тезисы: 1. Алерты (события) - глючность, они не всегда работают. Поэтому выборка данных производится исключительно селектами. 2. Уменьшение количества записей в основной таблице до 1000 приводит к приемлимой нагрузке, доведение до 3-4 тысяч - к неприемлимой. 3. Для обеспечения приемлимой работоспособности необходимы архивные таблицы (они сделаны на других серверах). Для нормальной структуры БД с ссылочной целостностью оч. большой геморрой делать архивные таблицы - практически целостность убивается т.к. объект на который ссылаются может кочевать по разным таблицам. ХОЧЕТСЯ И ЦЕЛОСТНОСТИ И БЫСТРОДЕЙСТВИЯ! Часть базы является динамической - должна быть быстрой, часть архивной - десятки миллионов записей. Есть понятие секционированные таблицы - но они тока в Оракле. Можно сделать ключ на вьюшку, объединяющую основную и архивную таблицы - тоже тока в Оракле. Конечно, варианты с алертами не отброшены, но в случае провала их использования структура меняться не должна. Мой вариант: одна таблица с индексом по Состоянию. 2 вьюшки - одна заточена на Состояние = 10 (архив) другая наоборот Состояние <> 10 (рабочая). Вьюшки предназначены для большего разграничения доступа к таблице, что б каждая использовалась в своем контексте. Думается, что select * from work_view where State = n не должен занимать много ресурсов? Что посоветуете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 14:47 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
IB - это не Оракл и запросы на представления с UNION ALL мягко говоря буду мало оптимальными. Я тут вижу 2 направления, над которыми можно поразмыслить: 1) Всё будет лежать в одной таблице с целочисленным первичным ключём. Также должна быть таблица, в которой будут храниться пороговые значения ключа, например сегодня записи начиная с номера 1000 - это оперативные данные, а начиная с номера 500 - это данные за текущий месяц. Ну и соответственно построить представления, в которых для отбора будет использоваться этот ключ (возможно его лучше сделать составным). 2) Создать несколько таблиц с избыточностью данных. Организовать бизнес логику так, чтобы при изменении данных в основной таблице делались нужные изменения также в таблице оперативных данных и таблице данных за весь месяц. Что бы я из этого выбрал - я не знаю. Тут надо думать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 15:50 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Собственно порогом является архивное значение Состояния (10). Вопрос насколько быстродействующая схема получится если в одну таблицу все забабахать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 16:01 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Ну всё это сложно, конечно. Быстродействие зависит от многих факторов. Вот я когда-то тупо свою базу на Линукс скопировал и там расчёты запустил - чудеса!!! всё раза в 3 быстрее считалось. Почитай статьи на ibase.ru о стоимости доступа к данным, о выборе оборудования, о выборе размеров страницы БД и т.п. - всё это может сильно повлиять на конечный результат. Я думаю что тормозить начнёт когда в таблице будет записей миллионов эдак надцать... Хотя это отфонарная оценка. Можно и на тысяче записей тормоза поиметь... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 16:10 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
1. Алерты (события) - глючность, они не всегда работают. Поэтому выборка данных производится исключительно селектами. ? В смысле, как второе вытекает из первого? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 16:17 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
to Gold: О том и речь, что можно (и нужно) много чего почитать, но наверняка кто-нить делал что то подобное и знает чем это кончилось. Передо мной - негативный пример, но там много огрехов, потому и переписываем. Живая ли схема что я предложил? Т.е. записи из таблицы не удаляются вообще. И добавляются тысячами в день. Порядка 20 выборок в секунду с 300 клиентов select count(*) from sometable where State=n. По State построен индекс. Время добавления записи не так критично. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 16:20 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
авторПорядка 20 выборок в секунду с 300 клиентов select count(*) Я бы такое на IB не рискнул делать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 16:30 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
сталкивался с аналогичной проблемой. из-за тормозов данные пришлось разнести на две таблицы: оперативные - в одной, архивные - в другой. СУБД: MSSQL. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 16:30 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
to mv: Как мне видится варианты обновления информации на клиентах: 1. Подписка на событие. По приходу события выборка. Наиболее грамотно. Но есть подозрение что не устроит по надежности. Думаю, что можно контрольный селект сделать, зарядить его если алерт не появляется минут 5. Типа повысить надежность. Хотя мне кажется инфа о глючности алертов преувеличена. Все зависит от рук. 2. Селект по таймеру. Не грамотно. Сопряжено с серьезным увеличением нагрузки на сервак. 3. Написать тригер, который что-нить выполняет. Например, заносит нечто в вспомогательную таблицу, откуда клиенты селектом выбирают признак обновления данных. Коллеги отговаривают. 4. Написать свою реализацию алертов. Пожалуй самый тернистый путь. Хотя много где обсуждался и есть с чего сдирать. Тернист из-за завязки на конкретную реализацию. Хотелось бы от этого уйти. По большому счету - выбор между селектами и алертами. Или еще чего-то? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 16:30 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
2 Dedushka Mazai: Как с целостностью порешили? Отказались или наворачивали дубляжи таблиц? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 16:34 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Порядка 20 выборок в секунду с 300 клиентов select count(*) from sometable where State=n. Мысли вслух: Если вариантов значений State немного, можно поступить как-нибудь так: Табличка State_T: (state : integer Counter : integer); Триггеры - After Insert --------- declare variable cnt integer; ... select count(*) from State_T into :cnt where State = New.State; if cnt <> 0 then insert into State_t (State, Counter) values (New.State, 1) else update State_t set Counter = Counter + 1 where State_t.State = New.State After delete --------- ... update State_t set Counter = Counter - 1 where State_t.State = Old.State After update --------- if (old.State <> new.State) then begin UPDATE State_t T SET T.Counter=T.Counter-1 WHERE T.State = old.State; UPDATE State_t T SET T.Counter=T.Counter+1 WHERE T.State = new.State; end И далее в том же духе. Естественно, "пишущие" транзакции д.б. с соответствующим уровнем изоляции. А юзеры просто выбирают вместо select count(*) from sometable where State=n - select State_t.Counter from State_t where State=n Ну, еслши нужно, чтобы не заводить много табличе, можно завести доп поле - идентификатор, что это за sometable: select State_t.Counter from State_t where State=n and Sometable = 'Table_One' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 16:51 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
к сожалению, не помню, так как это было давно и делалось не мной. вроде как с целостностью проблем не было, так как на данные никто не ссылался: они просто накапливались и по ним строилась статистика ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 16:51 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
2 mv IMHO: этот эффект можно получить индексом: (status_id, id), притом индекс может работать быстрее т.к. нету расходов на вызов update/insert. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2004, 17:29 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Вообще странно, что выборка 1000 или 3000-4000 тысяч активных записей может вызывать проблемы. Для Oracle если по state сделать индекс и если при этом занчением "архивная" будет не 10 а NULL (NULL значения в Oracle не попадают в индекс) то мы получим маленький компактненький индекс для выборки записей в активном состоянии (от 1 до 9), и не надо никаких архивных таблиц. Соответственно никаких проблем со ссылочной целостностью, запись как лежала в одной таблице , так и продолжает лежать. Как поступает IB с NULL значениями в индексе не знаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2004, 10:19 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
ИБ вроде как тоже NULL-значения не индексирует... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2004, 12:51 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Ошибаешься ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2004, 12:58 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Хм, помниться ещё об этом в конференции споры были. Я Д. Еманову показывал из Open feature request: автор 451953 Indexes with NULLs Feature request Allow for NULL values to be included in the index data, using the syntax: CREATE [WITHNULLS] INDEX... Он мне тогда сказал что это совсем из другой оперы, но чё-то мне показалось что NULLы не индексируються :-/ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2004, 13:06 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Индексируются. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2004, 13:18 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
А что это тогда за CREATE [WITHNULLS] INDEX... ??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2004, 13:22 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2004, 13:26 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
GoldА что это тогда за CREATE [WITHNULLS] INDEX... ??? Понятия не имею. Этот feature request не я писал ;-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2004, 13:33 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Хм... я чего-то не понимаю... Вы извините, я человек простой и привык все ручками щупать. Так вот: Машина: PIV2GHz 256RAM Win2K Prof FB.RC7 Super База: Естественно кеш не 2048 а немного больше, всего на один нолик. Остальное в конфигурации by default. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Скрипт заполения базы: Код: plaintext 1. 2. 3. 4. 5. 6. 7. Клиент: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Да, я понимаю что записи отбираются каждый раз одни и те же, но т.к. у dao+ обновление данных идет не очень активно я решил им пренебречь, но чтобы как-то компенсировать, клиенты дают запрос не каждые 15, а каждые 10 секунд. Итак: 400 коннектов загрузка процессора ~80% 500 коннектов загрузка процессора ~95% так же немогу не отметит что запуганый этим топиком я сначала тестировал не на такой базе, а на базе заполненой так: execute procedure AddRecs(100, 1); execute procedure AddRecs(100, 2); ... результаты были лишь немного лучше. Ктому же, господин dao+ говорит что "Есть система под Oracle", а InterBase это "для установки на объекты с меньшим количеством пользователей и интенсивностью запросов". 400 запросов достаточно меньшая интенсивность? Причина по которой такая система может тормозить, приходит на ум такая: в Informix если в предложении select были только те поля которые есть в индексе который использовался при отборе, то страници самой таблици не считывались в память а значения в результат брались из самого индекса. То же самое и для результирующих запросов при отборе которых использовался один индекс. Проще говоря в Informix запрос Код: plaintext был бы выполнен без чтения страниц таблици tbl1 с диска. У меня есть подозрение, что IB/FB так неможет впринципе. Почему: потому что даже при чтении вопервых должна идти уборка мусора, а вовторых IB/FB должен поставить какой-то флаг в заголовке записи. Хотя помоему для red_committed транзакций это возможно лишнее. Короче. Есть предложение разделить таблицу, но не вертикально (архив/актив), а горизонтально (ключ/данные) тоесть: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Связь по Id 1к1. Тогда если при выполнении запроса дергаются страници данных таблици, страниц будет гораздо меньше. Можно даже в TData завести копию поля Status, чтоб при запросах к TData не надо было лезть за статусом в TStatus. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.02.2004, 22:59 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Andrey_ Короче. Есть предложение разделить таблицу, но не вертикально (архив/актив), а горизонтально (ключ/данные) тоесть Совершенно верно, так и надо. Пришел к тем же результатам. С индексами IB 6.5 (думаю что и другие версии IB тоже) работает самым непонятным образом. И для моей задачи эти капризы не подходят. (Смотрел планы и Performance analysis в IBManager). Так что первоначальный вариант с индексацией по полю state в IB может не прокатить. Кстати, господа, советую поглядывать в Performance analysis - оч интересные и неочевидные вещи можно обнаружить. Например, select .... where state > 1 и where state >=2 совершенно разные запросы в моем случае, хотя результат и смысл один. И если архивные записи хранятся state = 1 то первый запрос сделает посути fullscan хотя и по индексу а второй пробежит тока нужные записи. А если архивные записи хранятся state = 10 а не архивные значение меньше, то как не крути - fullscan. Индексы сделал и восходящие и нисходящие - бестолку. А вот с внешней таблицей все вроде как хорошо получается и не зависит от выбранной СУБД. С планами и анализом выполнения тоже все хорошо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2004, 10:06 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
>select .... where state > 1 и where state >=2 совершенно разные запросы\r \r >если архивные записи хранятся state = 10 а не архивные значение меньше, то как не крути - fullscan\r \r Вы сами себе противоречите, а как же state<=9 :)\r \r Если интересно, я когда-то делал еще тест на этом же железе.\r \r \r Мой вывод такой: при отсутствии тяжелых запросов и присутствии PIV2GHz c Win2K Prof, FB1.5 RC7 спокойно держит 300 пишущих/читающих коннектов.\r \r Естественно объем RAM подлежит расчету. Для такого расчета можно отталкиватся от статьи . + от того что для любого запроса происходит чтение страниц даннх таблиц. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2004, 11:59 |
|
||
|
Целостность vs Быстродействие. Переносить ли в архивную таблицу?
|
|||
|---|---|---|---|
|
#18+
Andrey_У меня есть подозрение, что IB/FB так не может в принципе. Почему: потому что даже при чтении во-первых должна идти уборка мусора, а во-вторых IB/FB должен поставить какой-то флаг в заголовке записи. Хотя по-моему для read_committed транзакций это возможно лишнее. Это все сочинительство. Ключ индекса не хранит номер транзакции, так что для определения валидности записи для текущей транзакции надо лезть за этой записью на страницы данных и читать tra_number для всех ее версий с целью поиска подходящей. Других причин невозможности full index scan нет. dao+С индексами IB 6.5 (думаю что и другие версии IB тоже) работает самым непонятным образом. Все зависит от желания разобраться. dao+Кстати, господа, советую поглядывать в Performance analysis - оч интересные и неочевидные вещи можно обнаружить. Например, select .... where state > 1 и where state >=2 совершенно разные запросы в моем случае, хотя результат и смысл один. И если архивные записи хранятся state = 1 то первый запрос сделает посути fullscan хотя и по индексу а второй пробежит тока нужные записи. Угу, есть такая негативная особенность. Хотя с неочевидностью я бы поспорил ;-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.02.2004, 14:04 |
|
||
|
|

start [/forum/topic.php?fid=40&msg=32412296&tid=1579154]: |
0ms |
get settings: |
11ms |
get forum list: |
21ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
184ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
64ms |
get tp. blocked users: |
2ms |
| others: | 277ms |
| total: | 575ms |

| 0 / 0 |
