У меня следующий запрос:
SELECT location, step, COUNT(*), AVG(foo), YEAR(start), MONTH(start), DAY(start)
FROM table WHERE jobid = 'xxx' AND start BETWEEEN '2010-01-01' AND '2010-01-08'
GROUP BY location, step, YEAR(start), MONTH(start), DAY(start)
Изначально у меня были индексы по отдельным столбцам, такие как jobid и start , но я быстро понял, что MySQL действительно учитывает только один индекс на таблицу в выборке. Таким образом, он будет использовать индекс jobid , а затем выполнит довольно большое сканирование для фильтрации по диапазону start .
Добавление индекса для ( jobid , start ) очень помогло, но GROUP BY по-прежнему вызывает проблемы с производительностью. Я прочитал документы по оптимизации GROUP BY и понимаю, что для получения выгоды от этих оптимизаций мне нужен индекс, который содержит ( location , step , start ), но у меня все еще есть два открытых вопроса:
Будет ли группа при оптимизации работать даже с функциями времени (ГОД, МЕСЯЦ, ДЕНЬ и т. Д.)? Или мне придется хранить эти значения в виде отдельных столбцов? Причина, по которой мне нравится выполнять функции, заключается в том, что я могу управлять часовым поясом для каждого соединения и получать результаты, адаптированные к часовому поясу конечных пользователей. Если мне нужно предварительно сохранить год, месяц и день, я сделаю это через UTC, и тогда все мои пользователи будут просто получать отчеты в формате UTC.
Даже если я смогу решить проблему № 1, могу ли я это сделать? Индекс ( jobid , start ) помог с предложением WHERE, но GROUP BY требуется другой индекс для оптимизации ( location , step , начало ) или, в зависимости от ответа на # 1, ( местоположение , шаг , год , месяц , , день ). Но проблема в том, что эти два индекса не имеют общего левого набора столбцов, поэтому я не верю, что мои WHERE и GROUP by могут быть совместимы, так что используется один и тот же индекс. Итак, мой вопрос: я только что накрылся здесь?
Любые другие мысли о том, как этого добиться, были бы полезны. И, просто, чтобы предупредить несколько вопросов / комментариев, которые могут возникнуть:
- Да, это набор данных временных рядов.
- Да, было бы полезно что-то вроде RRDtool , но из-за этого я потерял бы результаты, зависящие от часового пояса.
- Да, предварительный расчет накопительных пакетов, вероятно, был бы хорошей идеей, но мне не нужна потрясающая производительность, и поэтому я в порядке с хорошей производительностью, если она позволяет мне настраивать результаты для часового пояса каждого пользователя.
С учетом вышесказанного, если у кого-то есть какие-либо конструктивные предложения о том, как сделать что-то вроде свертки или циклических баз данных и при этом получить результаты, зависящие от часового пояса, я весь слух!
Обновление : по запросу, вот еще некоторая информация:
показать индексы с выхода:
step 0 PRIMARY 1 step_id A 16 NULL NULL BTREE
step 1 start 1 start A 16 NULL NULL BTREE
step 1 step 1 step A 2 NULL NULL BTREE
step 1 foo 1 foo A 16 NULL NULL YES BTREE
step 1 location 1 location A 2 NULL NULL YES BTREE
step 1 jobid 1 jobid A 2 NULL NULL YES BTREE
показать создать вывод таблицы:
CREATE TABLE `step` (
`start` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`step` smallint(2) unsigned NOT NULL,
`step_id` int(8) unsigned NOT NULL AUTO_INCREMENT,
`location` varchar(12) DEFAULT NULL,
`jobid` varchar(37) DEFAULT NULL,
PRIMARY KEY (`step_id`),
KEY `start_time` (`start`),
KEY `step` (`step`),
KEY `location` (`location`),
KEY `job_id` (`jobid`)
) ENGINE=InnoDB AUTO_INCREMENT=240 DEFAULT CHARSET=utf8