У нас в одном проекте товарищ написал на С++ свой data storage. Работает быстро, но глючно. Решил я тут попробовать на MySQL базу заюзать, честно говоря не ожидал, совсем не в восторге.
В базе одна таблица, примерно такая:
id int primary key,
msisdn varchar (11),
starttime datetime,
xdr blob(1024);
id, msisdn, starttime имеют индексы, именно по ним будет осуществляться поиск.
Предполагается хранить примерно около ~200 000 000 записей. Частая операция INSERT, UPDATE вообще не будет, DELETE не часто.
Сделал тестовое приложение, на С++. Вставка в чистую БД 200 000 000 записей заняла 10 часов примерно.
Вот такой запрос выполняется 28 минут: select count(*) from test_table where msisdn='84537683151';
Размер файла на диске занял 212Gb данные, 6Gb файл индексов.
Характеристики компа: IBM Blade HS20, два проца Intel Xeon, 4Gb памяти.
Что не так? В чём проблема? С удовольствием принимаю все советы и рекомендации.
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Здравствуйте, Smooky, Вы писали:
S> Сделал тестовое приложение, на С++. Вставка в чистую БД 200 000 000 записей заняла 10 часов примерно. S> Вот такой запрос выполняется 28 минут: select count(*) from test_table where msisdn='84537683151';
Тип таблицы? msisdn — это текст или все же число и какой результат дал запрос выше (сколько там реально count)?
Здравствуйте, Anton Batenev, Вы писали:
AB>Здравствуйте, Smooky, Вы писали:
S>> Сделал тестовое приложение, на С++. Вставка в чистую БД 200 000 000 записей заняла 10 часов примерно. S>> Вот такой запрос выполняется 28 минут: select count(*) from test_table where msisdn='84537683151';
AB>Тип таблицы? msisdn — это текст или все же число и какой результат дал запрос выше (сколько там реально count)?
Тип MyISAM. msisdn — это текст, но поскольку в INT он может не влазить, то тип varchar(11). Результат 600 записей.
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Здравствуйте, Smooky, Вы писали:
S>Здравствуйте, Anton Batenev, Вы писали:
AB>>Здравствуйте, Smooky, Вы писали:
S>>> Сделал тестовое приложение, на С++. Вставка в чистую БД 200 000 000 записей заняла 10 часов примерно. S>>> Вот такой запрос выполняется 28 минут: select count(*) from test_table where msisdn='84537683151';
AB>>Тип таблицы? msisdn — это текст или все же число и какой результат дал запрос выше (сколько там реально count)?
S>Тип MyISAM. msisdn — это текст, но поскольку в INT он может не влазить, то тип varchar(11). Результат 600 записей.
насколько разные первые N символов в msisdn? Если нет такого, что 99% записей начинаются с трех одинаковых цифр, то можно попробовать сделать индекс по первым N символам (чем больше N, тем больше размер индекса и пересчет его при инсерте). После создания индекса, попробуйте заново загнать весь датасет и засечь, сколько это займет. Будет однозначно больше, вопрос насколько. Основная часть запросо будет только с where msisdn='XXX'? Что говорит show create table `table` ?
Здравствуйте, odesk_worker, Вы писали:
_>Здравствуйте, Smooky, Вы писали:
S>>Здравствуйте, Anton Batenev, Вы писали:
AB>>>Здравствуйте, Smooky, Вы писали:
S>>>> Сделал тестовое приложение, на С++. Вставка в чистую БД 200 000 000 записей заняла 10 часов примерно. S>>>> Вот такой запрос выполняется 28 минут: select count(*) from test_table where msisdn='84537683151';
AB>>>Тип таблицы? msisdn — это текст или все же число и какой результат дал запрос выше (сколько там реально count)?
S>>Тип MyISAM. msisdn — это текст, но поскольку в INT он может не влазить, то тип varchar(11). Результат 600 записей.
_>насколько разные первые N символов в msisdn? Если нет такого, что 99% записей начинаются с трех одинаковых цифр, то можно попробовать сделать индекс по первым N символам (чем больше N, тем больше размер индекса и пересчет его при инсерте). После создания индекса, попробуйте заново загнать весь датасет и засечь, сколько это займет. Будет однозначно больше, вопрос насколько. Основная часть запросо будет только с where msisdn='XXX'? Что говорит show create table `table` ?
Можно попробовать сделать char(11) вместо варчара, но размер на диске тогда еще увеличится по идее.
Здравствуйте, Smooky, Вы писали:
S> S>> Сделал тестовое приложение, на С++. Вставка в чистую БД 200 000 000 записей заняла 10 часов примерно. S> S>> Вот такой запрос выполняется 28 минут: select count(*) from test_table where msisdn='84537683151'; S> AB>Тип таблицы? msisdn — это текст или все же число и какой результат дал запрос выше (сколько там реально count)? S> Тип MyISAM. msisdn — это текст, но поскольку в INT он может не влазить, то тип varchar(11). Результат 600 записей.
msisdn можно сделать типом BIGINT — в этом случае войдет число достаточного размера. К слову, на поле установлен NOT NULL?
Теперь что касается запроса — 6GB индекс, по хорошему, будет требовать ~6GB key_buffer_size (подробнее см. The MyISAM Key Cache) для более-менее быстрой работы.
Здравствуйте, odesk_worker, Вы писали:
_>насколько разные первые N символов в msisdn? Если нет такого, что 99% записей начинаются с трех одинаковых цифр, то можно попробовать сделать индекс по первым N символам (чем больше N, тем больше размер индекса и пересчет его при инсерте). После создания индекса, попробуйте заново загнать весь датасет и засечь, сколько это займет. Будет однозначно больше, вопрос насколько. Основная часть запросо будет только с where msisdn='XXX'? Что говорит show create table `table` ?
Да, возможно что первые 5 символов в msisdn будут во всех записях одинаковые.
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
| test | CREATE TABLE `test` (
`id` int(11) NOT NULL auto_increment COMMENT 'Unique Identifier',
`msisdn` varchar(11) NOT NULL COMMENT 'Mobile Station Integrated Services Digital Number',
`starttime` datetime NOT NULL COMMENT 'Call Start Date Time',
`xdr` blob COMMENT 'XDR Record',
PRIMARY KEY (`id`),
KEY `idx_msisdn` (`msisdn`),
KEY `idx_time` (`starttime`)
) ENGINE=MyISAM AUTO_INCREMENT=223104342 DEFAULT CHARSET=latin1 |
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Здравствуйте, Smooky, Вы писали:
S>Здравствуйте, odesk_worker, Вы писали:
_>>насколько разные первые N символов в msisdn? Если нет такого, что 99% записей начинаются с трех одинаковых цифр, то можно попробовать сделать индекс по первым N символам (чем больше N, тем больше размер индекса и пересчет его при инсерте). После создания индекса, попробуйте заново загнать весь датасет и засечь, сколько это займет. Будет однозначно больше, вопрос насколько. Основная часть запросо будет только с where msisdn='XXX'? Что говорит show create table `table` ?
S>Да, возможно что первые 5 символов в msisdn будут во всех записях одинаковые.
Если такая ситуация вероятна, то, может, имеет смысл вынести этот префикс из 5 цифр первых в отдельную колонку? Зачем: для того, чтобы потом сделать индекс только по второй части , тогда теоретически where first_part = "XXX" and second_part = "YYY" будет его использовать, ну и как бонус, можно влезть в просто инт с каждой из частей? Но, конечно, такой подход заставляет менять код и разбирать в нем строку на две эти части.
S>id, msisdn, starttime имеют индексы, именно по ним будет осуществляться поиск.
судя по именам телефония?
S>Характеристики компа: IBM Blade HS20, два проца Intel Xeon, 4Gb памяти.
оперативки мало
S>Вот такой запрос выполняется 28 минут: select count(*) from test_table where msisdn='84537683151';
200GB / 30min =~ 100mb/sec, тупо полный скан — предсказуемый результат.
S>Что не так? В чём проблема?
в MySQL. <режим телепата включен> И будет в том что ты решил хранить сериализованные данные в блобе чтобы потом их массово читать и обрабатывать
S>С удовольствием принимаю все советы и рекомендации.
выкинуть MySQL и начать с описания бизнес-задач
Здравствуйте, Miroff, Вы писали:
Q>>Oracle. M>Вас не затруднит оценить производительность Oracle на той же задаче на данном железе?
У меня есть опыт сравнения Oracle и MySQL на одинаковых задачах на одинаковом железе. Не на таком, но в относительных тестах это не важно.
Здравствуйте, Miroff, Вы писали:
S>>Что не так? В чём проблема? С удовольствием принимаю все советы и рекомендации. M>Как минимум индекс должен целиком помещаться в память.
Ага, а лучше -- вся база. MySQL только в таких условиях работает нормально.
На Хабре кстате сведения не совсем точны... я где то читал блог одного из инженеров Фэйсбука, сцылку ща не найду, но там была примерно так: 1805 серверов — кластеры на MySQL, 807 servers memcached.
Это чтож получается, как только требуется решить задачу с более менее приличным кол-вом данных, то надо срочно бежать покупать Data Center где нить в Калифорнии?
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Здравствуйте, quwy, Вы писали:
Q>У меня есть опыт сравнения Oracle и MySQL на одинаковых задачах на одинаковом железе. Не на таком, но в относительных тестах это не важно.
И? Результат-то огласите. Как себя поведет Oracle в случае одной большой таблицы у которой даже индексы не влезают в память. Мой опыт подсказывает, что чудес не бывает и цифры будут сопоставимы.
Здравствуйте, Smooky, Вы писали:
S>Всем привет!
S>У нас в одном проекте товарищ написал на С++ свой data storage. Работает быстро, но глючно. Решил я тут попробовать на MySQL базу заюзать, честно говоря не ожидал, совсем не в восторге.
S>В базе одна таблица, примерно такая: S>id int primary key, S>msisdn varchar (11), S>starttime datetime, S>xdr blob(1024);
S>id, msisdn, starttime имеют индексы, именно по ним будет осуществляться поиск. S>Предполагается хранить примерно около ~200 000 000 записей. Частая операция INSERT, UPDATE вообще не будет, DELETE не часто.
S>Сделал тестовое приложение, на С++. Вставка в чистую БД 200 000 000 записей заняла 10 часов примерно. S>Вот такой запрос выполняется 28 минут: select count(*) from test_table where msisdn='84537683151'; Именно такой запрос будет выполняться приметно одинаковое время для любой СУБД, так как сводится тупо к сканированию всей таблицы с поднятием её с диска.
В реальности же наверняка будут другие запросы, зачем оптимизировать структуру под этот искуственный?
Если же в приложении и вправду нужно знать количество записей, то можно его получать более быстрыми способами.
Здравствуйте, vmpire, Вы писали:
S>>id, msisdn, starttime имеют индексы, именно по ним будет осуществляться поиск. S>>Вот такой запрос выполняется 28 минут: select count(*) from test_table where msisdn='84537683151';
V>Именно такой запрос будет выполняться приметно одинаковое время для любой СУБД, так как сводится тупо к сканированию всей таблицы с поднятием её с диска.
Это почему вдруг? Если значения msisdn распределены достаточно равномерно нормальная СУБД не станет делать скан.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Здравствуйте, AndrewJD, Вы писали:
AJD>Здравствуйте, vmpire, Вы писали:
S>>>id, msisdn, starttime имеют индексы, именно по ним будет осуществляться поиск. S>>>Вот такой запрос выполняется 28 минут: select count(*) from test_table where msisdn='84537683151';
V>>Именно такой запрос будет выполняться приметно одинаковое время для любой СУБД, так как сводится тупо к сканированию всей таблицы с поднятием её с диска. AJD>Это почему вдруг? Если значения msisdn распределены достаточно равномерно нормальная СУБД не станет делать скан.
Тьфу, простите, не заметил WHERE.