Я хотел бы задать вопрос о том, как улучшить производительность в большой таблице MySQL с использованием InnoDB двигателя:Повышение производительности в большой таблице MySQL
Там в настоящее время таблицы в моей базе данных с около 200 миллионов строк. В этой таблице периодически хранятся данные, собранные различными датчиками. Структура таблицы выглядит следующим образом:
CREATE TABLE sns_value (
value_id int(11) NOT NULL AUTO_INCREMENT,
sensor_id int(11) NOT NULL,
type_id int(11) NOT NULL,
date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
value int(11) NOT NULL,
PRIMARY KEY (value_id),
KEY idx_sensor id (sensor_id),
KEY idx_date (date),
KEY idx_type_id (type_id));
Сначала я подумал о разбиении таблицы в месяцах, но из-за неуклонное добавление новых датчиков он достигнет текущего размера примерно через месяц.
Другим решением, которое я придумал, было разбиение стола на датчики. Однако из-за предела 1024 разделов MySQL это не вариант.
Я считаю, что правильное решение будет использовать таблицу с той же структурой для каждого из датчиков:
sns_value_XXXXX
Таким образом, был бы больше, чем 1.000 столов с предполагаемого размером 30 миллионов строк в год. В то же время эти таблицы могут быть разделены на несколько месяцев для обеспечения быстрого доступа к данным.
Какие проблемы могут возникнуть в результате этого решения? Существует ли более нормализованное решение?
Редактирование с дополнительной информацией
Я считаю, что стол должен быть большим по отношению к серверу:
- Облако 2xCPU и 8 Гб памяти
- ЛАМПА (CentOS 6.5 и MySQL 5.1.73)
Каждый датчик может иметь более одного типа переменных (CO, CO2 и т. Д.).
я в основном имеют две медленные запросы:
1) Ежедневное резюме для каждого датчика и типа (ср, макс, мин):
SELECT round(avg(value)) as mean, min(value) as min, max(value) as max, type_id
FROM sns_value
WHERE sensor_id=1 AND date BETWEEN '2014-10-29 00:00:00' AND '2014-10-29 12:00:00'
GROUP BY type_id limit 2000;
Это занимает более 5 мин.
2) вертикального до горизонтального просмотра и экспорта:
SELECT sns_value.date AS date,
sum((sns_value.value * (1 - abs(sign((sns_value.type_id - 101)))))) AS one,
sum((sns_value.value * (1 - abs(sign((sns_value.type_id - 141)))))) AS two,
sum((sns_value.value * (1 - abs(sign((sns_value.type_id - 151)))))) AS three
FROM sns_value
WHERE sns_value.sensor_id=1 AND sns_value.date BETWEEN '2014-10-28 12:28:29' AND '2014-10-29 12:28:29'
GROUP BY sns_value.sensor_id,sns_value.date LIMIT 4500;
Это также занимает более 5 мин.
Другие соображения
- Timestamps может повторяться из-за вставки характеристик.
- Периодические вставки должны сосуществовать с выборами.
- Обновления и удаления не выполняются на столе.
Предположение, сделанное в «одну таблицы для каждого датчика» подход
- Таблицы для каждого датчика будет намного меньше, так что доступ будет быстрее.
- Выборы будут выполняться только на одной таблице для каждого датчика.
- Выбор данных смешивания с разных датчиков не зависит от времени.
Update 02/02/2015
Мы создали новую таблицу для каждого года данных, которые мы также распределяли в ежедневной основе. Каждая таблица имеет около 250 миллионов строк с 365 разделами. Новый индекс используется, как предложил Олли (sensor_id, date, type_id, value), но запрос все еще занимает от 30 секунд до 2 минут. Мы не используем первый запрос (ежедневное резюме), а только второе (вертикальное и горизонтальное).
Для того, чтобы разбить таблицу, необходимо удалить основной индекс.
Мы что-то упускаем? Есть ли способ улучшить производительность?
Большое спасибо!
Какая проблема возникает с текущей структурой? –
Большой? Что здесь большое? – TomTom
Какова цель данных teis? Как его читать? – Aret