2012-03-04 5 views
0

У меня есть таблица статистики, которая растет с большой скоростью (около 25M строк в день), которую я хотел бы оптимизировать для избранных, таблица вписывается в память, и у сервера много резервной памяти (32G, таблица 4G).Оптимизация простого выбора mysql на большой таблице (75M + rows)

Мой простой рулонной запрос:

EXPLAIN select FROM_UNIXTIME(FLOOR(endtime/3600)*3600) as ts,sum(numevent1) as success , sum(numevent2) as failure from stats where endtime > UNIX_TIMESTAMP()-3600*96 group by ts order by ts; 
+----+-------------+--------------+------+---------------+------+---------+------+----------+----------------------------------------------+ 
| id | select_type | table  | type | possible_keys | key | key_len | ref | rows  | Extra          | 
+----+-------------+--------------+------+---------------+------+---------+------+----------+----------------------------------------------+ 
| 1 | SIMPLE  | stats  | ALL | ts   | NULL | NULL | NULL | 78238584 | Using where; Using temporary; Using filesort | 
+----+-------------+--------------+------+---------------+------+---------+------+----------+----------------------------------------------+ 

Статистика является таблицей InnoDB, есть нормальный индекс EndTime .. Как мне оптимизировать это?

Примечание: Я планирую добавлять таблицы свертывания, но в настоящее время это то, что я застрял, и мне интересно, можно ли исправить это без дополнительного кода приложения.

+0

Какие альтернативы вы попробовали с вашим запросом, чтобы попытаться избавиться от filesort? Вы пытались удалить заказ? Пробовали ли вы проверять конфигурацию своего сервера, чтобы убедиться, что он настроен на использование достаточной памяти? – imm

+0

Я не верю, что индексы работают в Calculated Fields в MySql - любой способ заменить их? – fatfrog

+0

Это поможет, если вы сможете объяснить, что этот запрос пытается выполнить. Разделение, а затем умножение на 3600 кажется излишним. Группируйте и заказывайте, добавив массу времени. Вы заказываете неиндексированное значение, которое добавляет тонны времени. Если вам нужно заказать, закажите по полю времени окончания и убедитесь, что он проиндексирован. – Cfreak

ответ

1

Я проводил местные тесты. Попробуйте следующее:

alter table stats add index (endtime, numevent1, numevent2); 

И удалить order by, как это должно быть неявным в group by (я предполагаю, что синтаксический анализатор просто игнорирует order by в этом случае, но только в том случае :)

+0

Это сокращает время запроса в 10 раз (3 минуты для запуска того же запроса). Любые другие советы? –

+0

Ницца :) Нет, ничего не могу думать о –

0

Поскольку вы используете InnoDB вы также можете попробовать следующее:

а) изменение innodb_buffer_pool_size 24ГБ (требуется перезапуск сервера) - который будет гарантировать, что вся ваша таблица может быть загружена в память, следовательно, ускорит сортировку даже таблица становится больше

b) Добавьте файл innodb_file_per_table, который заставляет InnoDB размещать каждое новое табличное пространство в своей собственной таблице. Вам необходимо отказаться от существующего стола и его воссоздать

c) Используйте самый маленький доступный размер столбца, который может соответствовать данным. Не видя фактических определений столбцов и некоторого образца, я не могу представить никаких конкретных идей. Можете ли вы предоставить примерную схему и, возможно, 5 строк данных

Смежные вопросы