[MySQL] Дизайн большой таблицы + настройка сервера
От: Mamut Швеция http://dmitriid.com
Дата: 24.12.08 13:34
Оценка:
Есть тупая до ужаса таблица
CREATE TABLE `price_detail` (
  `accomodation` int(11) NOT NULL,
  `date` datetime NOT NULL,
  `price` int(11) NOT NULL,
  `room_id` int(11) NOT NULL,
  KEY `idx_price_price` (`price`),
  KEY `idx_price_date` (`date`),
  KEY `idx_price_accomodation` (`accomodation`)
)


Предположим, что у нас в ту таблицу закладывается 3 миллиона строк на день. То есть нормально, чтобы уже сегодня нам пришдется работать с 3*365=1095 миллионов записей на будущий год. Причем в базе данных это — единственная таблица с таким количеством записей.

К таблице будут приходить простейшие запросы типа
SELECT 
  `price`
FROM
  `price_detail` 
WHERE
  `accomodation`=1
  AND
  `date` BETWEEN '2008-01-01 12:00:00.000' AND '2008-01-15 12:00:00.000'


80% запросов охватывают период до двух недель.

Изначально наша идея была разбить таблицу на partitions понедельно. Разбили. Приведеный запрос отрабатывает за время от 20 секунд (MacBook Pro, 2 GB RAM, настройки mysql сервера почти не менялись). А нужно — менее секунды

Собственно вопрос А что делать-то

1. Может лучше использовать merge table?
2. Поможет ли cover index по колонкам (date, accomodation, price) (или в другом порядке)
3. Что подкрутить в настройках?

В общем, на РСДН уповаю


dmitriid.comGitHubLinkedIn
Re: [MySQL] Дизайн большой таблицы + настройка сервера
От: pkarklin  
Дата: 24.12.08 13:48
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Есть тупая до ужаса таблица

M>
M>CREATE TABLE `price_detail` (
M>  `accomodation` int(11) NOT NULL,
M>  `date` datetime NOT NULL,
M>  `price` int(11) NOT NULL,
M>  `room_id` int(11) NOT NULL,
M>  KEY `idx_price_price` (`price`),
M>  KEY `idx_price_date` (`date`),
M>  KEY `idx_price_accomodation` (`accomodation`)
M>) 
M>


M>Предположим, что у нас в ту таблицу закладывается 3 миллиона строк на день. То есть нормально, чтобы уже сегодня нам пришдется работать с 3*365=1095 миллионов записей на будущий год. Причем в базе данных это — единственная таблица с таким количеством записей.


Эт что ж за организация такая, у которой каждый день меняется цена на 3 000 000 помещений (accoMModation)?!
Re: [MySQL] Дизайн большой таблицы + настройка сервера
От: Роман Дубров Украина Я@Blogspot
Дата: 24.12.08 14:08
Оценка: 16 (1)
Mamut пишет:

> 1. Может лучше использовать merge table?


надо пробовать, желательно уже на production железе. Но волшебства не ждите.

> 2. Поможет ли cover index по колонкам (date, accomodation, price) (или в

> другом порядке)

в указанном запросе нужен индекс [accomodation, date] — добавить дату в
idx_price_accomodation. Ну и посмотреть кардинальность существующих
индексов на реальных данных и explain что говорит.

> 3. Что подкрутить в настройках?


query cache включить в первую очередь и дать ему достаточно памяти
ну и innodb_buffer_pool_size увеличить можно.
самый простой способ — погонять сутки под реальной нагрузкой, а потом
посмотреть сервер статус из свежего phpMyAdmin-а, он довольно дельные
советы дает

PS: по поводу дизайна — поддерживаю pkarklin, но велосипед ваш — вам
виднее
Posted via RSDN NNTP Server 2.1 beta
http://www.linkedin.com/in/romandubrov .::. http://roman-dubrov.blogspot.com/ .::. http://www.flickr.com/photos/romandubrov/
Re: [MySQL] Дизайн большой таблицы + настройка сервера
От: Anton Batenev Россия https://github.com/abbat
Дата: 24.12.08 14:09
Оценка: 16 (1)
Здравствуйте, Mamut, Вы писали:

M> Предположим, что у нас в ту таблицу закладывается 3 миллиона строк на день.

...
M> 80% запросов охватывают период до двух недель.

Я правильно понял, что 80% запросов возвращают по 3 млн * 14 дней = 42 млн записей и эти 42 млн записей должны быть получены за время менее секунды?

Если правильно, то. Прикинем (грубо) размер одной строки 4 + 8 + 4 + 4 = 20 байт. 42 млн записей * 20 байт = 801 MB.

Т.е. ты хочешь поднять с винта 800 метров в секунду, и при этом наложить на них поиск по полю `accomodation` (т.к. в плане запроса наверняка сначала будет идти выборка по дате, а потом по accomodation)?

А ты получаешь 800МБ / 20 с = 40 метров в секунду, что где-то близко по скорости чтения с винта в идеальных условиях.

M> Собственно вопрос А что делать-то


Если я нигде не ошибся выше, то бей базу на жесткие диски (RAID, Stripe) — упрешься в скорость работы шины/контроллера (правда, достигнуть времени в 1с все равно не получится).
avalon 1.0b rev 142
Re: [Апдейт по задаче]
От: Mamut Швеция http://dmitriid.com
Дата: 24.12.08 15:29
Оценка:
M>Предположим, что у нас в ту таблицу закладывается 3 миллиона строк на день. То есть нормально, чтобы уже сегодня нам пришдется работать с 3*365=1095 миллионов записей на будущий год. Причем в базе данных это — единственная таблица с таким количеством записей.

Худший вариант не прокатит По новым вводным данным строк будет намного меньше

Их буде 162 000 в день. То бишь 1 134 000 в неделю и 59 130 000 в год

Но вопросы все равно остаются


dmitriid.comGitHubLinkedIn
Re[2]: [MySQL] Дизайн большой таблицы + настройка сервера
От: Anton Batenev Россия https://github.com/abbat
Дата: 24.12.08 15:33
Оценка:
Здравствуйте, Anton Batenev, Вы писали:

AB>Если я нигде не ошибся выше, то бей базу на жесткие диски (RAID, Stripe) — упрешься в скорость работы шины/контроллера (правда, достигнуть времени в 1с все равно не получится).


В догонку. MySQL для типа таблиц MyISAM может сам делить таблицу на чанки (которые, в свою очередь, можно раскидать по разным дискам (которые, в свою очередь, могут быть рэйдами)).

CREATE TABLE `test`
(
   ...
)
ENGINE = MyISAM
RAID_TYPE = STRIPED
RAID_CHUNKS = 255
RAID_CHUNKSIZE = 819200;


Максимальное значение RAID_CHUNKS составляет 255, что составляет почти 5 лет, разбитых по одной неделе. Осталось, подобрать RAID_CHUNKSIZE, такой, который бы вмещал одну неделю в один чанк и раскидать на 2 винта (ну или 1 день в 1 чанк и раскидать на 7 винтов и один винт для файла с индексами — в общем, варианты).
Re: [MySQL] Дизайн большой таблицы + настройка сервера
От: MasterZiv СССР  
Дата: 24.12.08 17:10
Оценка: 16 (1)
Mamut пишет:

> CREATE TABLE `price_detail` (

> `accomodation` int(11) NOT NULL,
> `date` datetime NOT NULL,
> `price` int(11) NOT NULL,
> `room_id` int(11) NOT NULL,
> KEY `idx_price_price` (`price`),
> KEY `idx_price_date` (`date`),
> KEY `idx_price_accomodation` (`accomodation`)
> )
>

Какой движок ?

Что такое `accomodation` ?

> К таблице будут приходить простейшие запросы типа

>
> SELECT
> `price`
> FROM
> `price_detail`
> WHERE
> `accomodation`=1
> AND
> `date` BETWEEN '2008-01-01 12:00:00.000' AND '2008-01-15 12:00:00.000'
>
> 80% запросов охватывают период до двух недель.
>
> Изначально наша идея была разбить таблицу на partitions понедельно.
> Разбили.

Думаю, зря.

Ответьте себе на один вопрос:
сколько % таблицы в записях приходится на условие

`accomodation`=1
AND
`date` BETWEEN '2008-01-01 12:00:00.000' AND '2008-01-15 12:00:00.000'

за две недели ?
Сколько записей это будет ?
И кому нужно будет такое кол-во записей ?


Приведеный запрос отрабатывает за время от 20 секунд (MacBook
> Pro, 2 GB RAM, настройки mysql сервера почти не менялись). А нужно —
> менее секунды

Гы, а если это невозможно ? Что значит нужно ?

> 2. Поможет ли cover index по колонкам (date, accomodation, price) (или в

> другом порядке)

Вам бы над кластерный индекс по (date, accomodation) или наоборот, в зависимости
от того, какое поле более селективно. На один день — 3 млн. А на один accomodation ?

> 3. Что подкрутить в настройках?

Да в общем это не главное. Запросы главнее.
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.