Задавайте вопросы, мы ответим
Вы не зашли.
Есть таблица содержащая логи пользователей, данных в таблицу добавляеться очень много, сейчас таблица весит 10 Гб и в ней уже больше 10 млн. записей
CREATE TABLE `logs` (
`id` int(10) unsigned NOT NULL auto_increment,
`userid` char(64) NOT NULL,
`date` datetime NOT NULL,
`data` longtext NOT NULL,
PRIMARY KEY (`id`),
KEY `userid` (`userid`),
KEY `date` (`date`),
FULLTEXT KEY `data` (`data`)
) ENGINE=MyISAM
Так вот вставки в данную таблицу очень сильно грузят винт, я думаю ее разбить на части по дням. Подскажите пожалуйста как это правильно сделать с помощью PARTITIONING.
Неактивен
http://dev.mysql.com/doc/refman/5.4/en/ … range.html , нижний пример
Неактивен
Так правильно будет
ALTER TABLE logs
PARTITION BY RANGE ( DATE(`date`)+0) (
PARTITIONS 356;
);
Отредактированно msasoft (12.03.2010 09:24:31)
Неактивен
Тогда логичнее использовать PARTITION BY HASH? Если тупо разбить на
356 кусков? Но тогда любой аггрегирующий запрос будет использовать
все разделы. А в случае partitioning неплохо бы использовать pruning
Неактивен
А можно подробнее про pruning
Неактивен
Неактивен
В общих чертах разобрался, выходит я разбиваю таблицу
ALTER TABLE logs
PARTITION BY HASH ( DATE(`date`)) PARTITIONS 356;
И тогда запрос типа SELECT * FROM `logs` WHERE `date`>'2010-03-01' AND `date`<'2010-03-10' будет искать только в нужных партициях и не будет лопатить все части, я правильно понял?
И еще вопрос будет ли нормлаьно работать полнотекстовый поиск?
Неактивен
Вот я как раз подозреваю, что в случае HASH он будет лопатить все разделы,
а если бы у Вас было PARTITION pMAY2010 VALUES LESS THAN '2010-04-01',
то это бы точно влезло на один раздел.
Полнотекстовый поиск должен работать так же, как и раньше.
Неактивен
Т.е. правильно сделать так
ALTER TABLE logs
PARTITION BY RANGE ( DATE(`date`)) (
PARTITION p20100101 VALUES LESS THAN ('2010-01-01'),
PARTITION p20100102 VALUES LESS THAN ('2010-01-02'),
.............
PARTITION p20101231 VALUES LESS THAN ('2010-12-31'),
PARTITION p2011 VALUES LESS THAN MAXVALUE
);
Но у меня тут сомнения что PARTITION продхватит дату в таком виде, он вроде как с целыми числами работает?????
Неактивен
Да, там действительно нужны числа. И, к сожалению, нельзя использовать
UNIX_TIMESTAMP(date). Кстати, никто не знает, почему?
Самое близкое, что может работать тут хорошо, — YEARWEEK(`date`).
Подозреваю, что такую странную функцию ввели именно для таких разбиений.
Неактивен
Наверное здесь нужно использовать функцию TO_DAYS
Отредактированно msasoft (12.03.2010 16:16:19)
Неактивен
Хм, отличная функция, не знал про нее, в документации она тоже почему-то не стоит в
date and time functions, только упоминается в partitioning Да, она в данном случае
идеальна.
Неактивен
И еще оказывается дата должна быть в первичном ключе.
Попутно второй вопрос как убрать партиции, но чтобы данные остались.
Неактивен
ALTER TABLE tablename REMOVE PARTITIONING;
Неактивен
Огромное спасибо за помощь. Единственное что хотелось бы отметить, полнотекстовый поиск к сожалению не поддерживается. Индексы FULLTEXT не дает создавать выдает ошибку, что данные индексы не поддерживаются выбранным типом таблиц. Также не поддерживаются INSERT DELAYED запросы.
Неактивен
msasoft написал:
Огромное спасибо за помощь. Единственное что хотелось бы отметить, полнотекстовый поиск к сожалению не поддерживается. Индексы FULLTEXT не дает создавать выдает ошибку, что данные индексы не поддерживаются выбранным типом таблиц.
Действительно, есть такое ограничение http://dev.mysql.com/doc/refman/5.4/en/ … tions.html
msasoft написал:
Также не поддерживаются INSERT DELAYED запросы.
Если вам нужно использовать INSERT DELAYED, скорее всего, у вас ошибки в архитектуре приложения.
DELAYED (insert, replace) позволяют накапливать в буфере на сервере INSERTы пока таблица не освободится. Возможна ситуация, что добавление и не произойдет, при этом не будет никаких сообщений об ошибке. В доке рекомендуют использовать DELAYED, если не критична потеря части информации.
Кроме того при каждом INSERT DELAYED опустошается кэш таблицы, а добавление когда ещё произойдет (если произойдет )
Неактивен
Я имел ввиду что при INSERT DELAYED выдает ошибку, что запросы не поддерживаються выбранным типом таблиц
Неактивен