Реляционные БД: пригодны ли для такого?
Вопрос: может ли переход на другую реляционную БД сильно улучшить ситуацию,В первую очередь поможет перепроектирование схемы данных. (Я не о приведенной табличке, с ней почти все в порядке, а в целом о базе). Я так понимаю, что тут речь идет о системе OLTP. В случае необходимости построения аналитических запросов, необходимо уже строить хранилище данных (OLAP). Естественно, есть специализированные реляционные СУБД заточенные для таких задач. Например, Terradata, Red Brick, Informix XPS, IBM DB2 Warehouse edition.
если да, то как примерно эта другая СУБД добьётся увеличения скорости:
Переход на что-то более продвинутое (типа FB, Oracle) только уменьшит производительность.
Переход на что-нибудь подобное по классу MySQL большого выигрыша в производительности все равно не даст.
Имхо, лучший выход - данные более 2-3-х месячной давности тупо сносить в архив, закатывать на болванку и забрасывать в далекий ящик. Можно при этом перед удалением старой детальной инфы какую-то более статистически укрупненную инфу (много меньшую детальной которая может пригодится для сбора отчетов и пр., сохранять в другой табличке.
MySQL, афаик, показывает одну из лучших производительностей на больших базах.Большие это сколько?
афаик, разработчики уверяют что обладают базой около террабайта...
Ну это явно не самая большая база в мире %). Кроме того, любая промышленная СУБД терабайт выдерживает легко, даже MS SQL (при условии, что с блокироваками напряги не возникнут %)
Фактически, отдельная база для таких запросов?
Тогда будет проще отказаться от реляционных баз и сделать что-то специализированное,
благо все типы запросов, которые нужно выполнять быстро, известны заранее.
Где можно это поботать ?
просто для определения порядка "большая".
Ну супер. Ещё велосипед изобретать... Ты твёрдо уверен, что тебе первому в мире пришло в голову решить эту задачу?
На сколько я представляю, это всевозможные представления базы, удобные для отчетов. Эти представления обновляются не в реал-тайме, а например, раз в сутки.
Не первому.
Например, разведка сообщает, что в хвалёном UTM тоже сделали специализированную нереляционную базу.
У нас в свое время руками делали процедуру "свертки" больших "исторических" таблиц в маленькие. Это, в частности, приводит к денормализации схемы.
Фактически, отдельная база для таких запросов?Да, у любого крупного предприятия, уже даже в России, для аналитических запросов используется отдельаная база. И действительно, далеко не всегда это реляционка. Очень часто используются многомерные СУБД. Но они не позволяют получать детальную инфомрацию и объем анализируем информации ограничивается где-то цифрой в 70-80 гб, дальше они не справляются. В таких случаях нужна реляционка, либо комбинация и той и другой.
Тогда будет проще отказаться от реляционных баз и сделать что-то специализированное,
благо все типы запросов, которые нужно выполнять быстро, известны заранее.
Насчет того, что запросы известны заранее, то в таком случае проще всего написать sql-запросы по существующей OLTP и воспользоваться какм-то механизмом для кэширования ответов, то есть чтобы такие запросы выполнялись реально ночью, а пользователи получали готовый результат. Проблема в том, что такие статичные отчеты подходят не часто, в большинстве случаев пользвователи хотят иметь возможность построения отчетов на лету (ad-hoc). То есть не идти каждый раз к программистам и ждать отчета неделю, а строить нужные отчеты мышкой, и не зная sql.
Многие делают. Мне тут недавно рассказывали, что биллинг то ли Билайна, то ли Мегафона использует специализированную базу.
Я собственно так и собираюсь сделать.
а че это за хранилище такое OLAP вообще?OLAP -online analytical processing
Хранилище данных в большинстве случаев синоним термину OLAP.
Где можно это поботатьДовольно-таки неплохая начальная информация в статьях на Olap.ru.
Самая лучшая инфа - книжки Ralph'a Kimball'a, на русском их к сожалению нет
Многие делают. Мне тут недавно рассказывали, что биллинг то ли Билайна, то ли Мегафона использует специализированную базу.И там и там да и в МТС тоже билинг на Оракле.
Скорее для решения каких-то подзадач (может, и связанных с билингом, используется что-то специализированное)
Мегафон сидит на постгресе
Мне рассказывали что там (где именно я забыл) бакенд на Оракле, а все рассчеты ведутся в специализированной базе.
не верю
Мегафон сидит на постгресеКак следующий раз буду с ихними айтишниками общаться обязательно спрошу есть ли у них что-нить на постгрессе. Очень сомневаюсь, ибо у постгресса, по моему опыту общения с ним, очень большие траблы с блокировками.
В мегафоне оракл, насколько я знаю, корпоративный стандарт. Даже в плане application server'ов, несмотря на то, что у Оракла они убогие.
в одной небезызвестной ERP системе для этого используют 2 таблицы: LedgerTrans, где лежат все проводки и LedgerBalancesTrans, в которой лежат суммы проводок по периодам (периоды настраиваются отдельно, обычно это месяцы и годы). Часть суммы считается по закрытым периодам, остальное досчитывается по LedgerTrans, работает быстро :-)
Агрегирование сделать легко, даже в реальном времени если понадобится. Тогда таблицы станут маленькими.Вот мне кажется, что это самый правильный подход.
Я собственно так и собираюсь сделать.
Все решается только перепроектированием базы. Результаты сложных запрсов (тех же месячных т.е. "отчеты" можно загонять в другие таблицы, например, а не генерить постоянно. А смена реляционной бд мало на что повлияет: та же беспорядочность в хранении строк - по сути заложена в спецификации sql.
А смена реляционной бд мало на что повлияет: та же беспорядочность в хранении строк - по сути заложена в спецификации sql.Вот это не совсем верно.
Год назад мне довелось позаниматься этой же проблемой. Правда там были бухгалтерские проводки. Результат был такой (в случае нашей конкретной системы что аналитические запросы mssql выполнял намного быстрее, чем mysql. Причем с ростом размера БД разрыв увеличивался. Если кому интересно, могу поподробнее рассказать, а то скажут, что обсираю mysql.
А насчёт "беспорядочности в хранении строк" она может и "заложена в спецификации sql", но кроме спецификации есть еще и реализация. А тут уже имеется поле для деятельности. Например можно (если СУБД поддерживает) создать materialized views (вспомогательную таблицу на крайняк в которых сделать кластерные индексы по тем полям, по которым будет происходить группировка. Иногда это может сильно сократить время построения аналитического отчета за счёт увеличения времени добавления одной записи в БД.
тут точно все правильно написано?:
сократить время построения аналитического отчета за счёт увеличения времени
2 : Чем больше индексов, тем больше времени тратится на добавление одной записи. Разве не так?
"В Советском Союзе секса нет" <c> (цитирую по памяти, а она мне бывает изменяет...) или чё?
Так но не линейно. Если включаешь индексы добавление/удаление записи вызывает еще и изменение в индексах, но если они на базе Б деревьев, то от количества индексов(размера базы) скорость почти не изменяется.
Ну я про линейность ничего и не говорил
По идее должна быть линейная зависимость от числа индексов.
ну да, я ступил, ну бывает в 4 утра
нп
А насчёт "беспорядочности в хранении строк" она может и "заложена в спецификации sql", но кроме спецификации есть еще и реализация.SQL не гарантирует хранение строк в каком-либо определенном порядке, посему завязывать на какие-то тонкости конкретной реализации более-менее серьезный проект не стоит.проект
Есть простейшая схема подсчёта трафика.Вообще, чтобы что-то понять, стоит указать запросы, которые ты в эту базу посылаешь. Также уточнить, что представляют из себя time и bytes. У меня на мускле трафик ложится вот в такую простую базу:
Данные о трафике закладываются примерно в такую таблицу:
code:
CREATE TABLE `ip_traffic` (
`id` bigint(20) NOT NULL,
`client` int(11) default NULL,
`class` smallint(6) default NULL,
`bytes` bigint(20) default NULL,
`time` bigint(20) default NULL,
PRIMARY KEY (`id`
KEY `i_time` (`time`,`client`
KEY `i_class` (`class`,`time`
KEY `i_client_time` (`client`,`time`
KEY `i_cct` (`client`,`class`,`time`)
)
Оно есть, и в целом неплохо работает.
Для каждого типичного вида запросов создано по индексу.
За несколько месяцев накапливается несколько гигабайт данных - в несколько раз больше объёма оперативной памяти на сервере.
Если пытаться складывать в таблицу более детальную информацию, данных будет ещё больше.
Проблема в том, что запросы, которым нужно перелопатить ну скажем несколько сот тысяч строк,
выполняются медленно.
Например, отчёт по месяцам, по трафику конкретного клиента - нужно, используя ключ `i_client_time`,
выбрать данные (их относительно немного, скажем около 1/1000 от всех строк и их немного обработать.
Но это делается несколько минут.
Как я понимаю, это происходит потому, что нужные строки разбросаны по всей таблице,
и нужно много операций чтения с диска, с позиционированием головки для каждой.
Используется MySQL.
Вопрос: может ли переход на другую реляционную БД сильно улучшить ситуацию,
если да, то как примерно эта другая СУБД добьётся увеличения скорости:
нужно ведь хранить данные так, чтобы для каждого индекса строчки хранились примерно в нужном порядке,
IMHO без дублирования тут не обойтись?
mysql> describe raw;Таблица counters - что и откуда снимать, raw - данные. Колонка raw.data - показания счетчика файерволла на момент времени raw.stamp, а raw.reload - индикатор сброса счетчика.
+--------+------------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------+------+-----+-------------------+-------+
| id | bigint(20) | | PRI | 0 | |
| data | bigint(20) | | | 0 | |
| stamp | timestamp | YES | PRI | CURRENT_TIMESTAMP | |
| reload | bigint(20) | YES | | NULL | |
+--------+------------+------+-----+-------------------+-------+
4 rows in set (0.02 sec)
mysql> describe counters;
+-----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+----------------+
| id | bigint(20) | | PRI | NULL | auto_increment |
| name | char(255) | YES | | NULL | |
| alias | char(255) | YES | | NULL | |
| rule | int(11) | | | 0 | |
| rule_body | char(255) | | | | |
| dir | enum('in','out') | | | in | |
+-----------+------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
Соответственно в моей конфигурации все запросы по сумме траффика за период выполняются быстро и просто.
Хотим узнать траффик id x за период с t1 по t2.
Идеал: reload(t1, x) = reload(t2, x) (т.е. счетчик не перегружался) считается банальной разницей raw.data(t2, x) - raw.data(t1, x наличие перезагрузок тоже не сильно влияет на сложность запроса и его производительность.
Да, забыл добавить - моя база на 10 счетчиках растет на 3Мб в месяц при снятии показаний раз в 20 мин.
SQL не гарантирует хранение строк в каком-либо определенном порядке, посему завязывать на какие-то тонкости конкретной реализации более-менее серьезный проект не стоит.проектВ данном случае это не тонкости, а заявленная фича программного продукта (clustered index). Иногда trade off при решении какой-то задачи смещен в пользу производительности, а не концепции. В этом случае вполне позволительно использовать и не такие особенности реализации...
И еще. Например биллинговая система, используемая компанией-сотовым оператором - это серьезный проект? imho серьезный. При этом заранее известно, что слезть с оракла на любую другую БД будет стоить этой компании, например, > 100 млн $. Стоит ли в такой ситуации завязываться на "какие-то тонкости конкретной реализации"? Вполне! Только нужно четко представлять, где проходит граница, чего еще можно, а чего уже нет. Ну это уже опыт и здавый смысл решают...
Согласен. )
SELECT FROM_UNIXTIME(time, '%Y/%m') as Month, class, sum(bytes) as B
FROM ip_traffic
WHERE client=$client AND time>=UNIX_TIMESTAMP($start_time)
GROUP BY Month, class
1) хранение заранее просчитаных выборок в отдельной таблице вида
------
id,
client,
class,
sum_bytes,
time,
enum type ("day", "month", "year")
------
2) Хранение в твоей таблице интегральных значений счетчиков вместо интервальных, тогда любой траффик за период - это разница двух значений, полученных двумя простыми запросами, которые будут выполняться быстрее, чем sum из-за которого и возникают тормоза.
Оставить комментарий
Marinavo_0507
Есть простейшая схема подсчёта трафика.Данные о трафике закладываются примерно в такую таблицу:
Оно есть, и в целом неплохо работает.
Для каждого типичного вида запросов создано по индексу.
За несколько месяцев накапливается несколько гигабайт данных - в несколько раз больше объёма оперативной памяти на сервере.
Если пытаться складывать в таблицу более детальную информацию, данных будет ещё больше.
Проблема в том, что запросы, которым нужно перелопатить ну скажем несколько сот тысяч строк,
выполняются медленно.
Например, отчёт по месяцам, по трафику конкретного клиента - нужно, используя ключ `i_client_time`,
выбрать данные (их относительно немного, скажем около 1/1000 от всех строк и их немного обработать.
Но это делается несколько минут.
Как я понимаю, это происходит потому, что нужные строки разбросаны по всей таблице,
и нужно много операций чтения с диска, с позиционированием головки для каждой.
Используется MySQL.
Вопрос: может ли переход на другую реляционную БД сильно улучшить ситуацию,
если да, то как примерно эта другая СУБД добьётся увеличения скорости:
нужно ведь хранить данные так, чтобы для каждого индекса строчки хранились примерно в нужном порядке,
IMHO без дублирования тут не обойтись?