Сортировка файлов MySQL по GROUP BY YEAR & Month - PullRequest
4 голосов
/ 24 февраля 2012

У меня есть большая таблица, в которой хранится отладочная информация для моего веб-приложения.Проблема в том, что в таблице теперь 500 000 строк, и один из запросов выполняется медленно, поскольку индекс не используется.

SQL:

EXPLAIN SELECT count(*) AS `count`, month(event_date) AS `month`, year(event_date) AS `year`FROM events WHERE 1 = 1 GROUP BY year(event_date) DESC, month(event_date) DESC LIMIT 6;

Результат:

SIMPLE  events  index   NULL    event_date  8   NULL    139358  Using index; Using temporary; Using file sort

А вот и структура таблицы.

CREATE TABLE IF NOT EXISTS `events` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Event Primary Key',
`event_number` int(11) NOT NULL,
`user_id` int(11) unsigned NOT NULL COMMENT 'User ID',
`server_id` int(11) unsigned DEFAULT NULL COMMENT 'The ID of the remote log client',
`remote_id` int(11) unsigned DEFAULT NULL COMMENT 'The Event Primary Key from the remote client',
`event_date` datetime NOT NULL COMMENT 'Event Datetime in local timezone',
`event_date_utc` datetime NOT NULL COMMENT 'Event Datetime in UTC timezone',
`event_type` varchar(255) NOT NULL COMMENT 'The type of event',
`event_source` varchar(255) NOT NULL COMMENT 'Text description of the source of the event',
`event_severity` varchar(255) NOT NULL COMMENT 'Notice, Warning etc',
`event_file` text NOT NULL COMMENT 'The full file location of the source of the event',
`event_file_line` int(11) NOT NULL COMMENT 'The line in the file that triggered the event',
`event_ip_address` varchar(255) NOT NULL COMMENT 'IP Address of the user that triggered the event',
`event_summary` varchar(255) NOT NULL COMMENT 'A summary of the description',
`event_description` text NOT NULL COMMENT 'Full description of the event',
`event_trace` text NOT NULL COMMENT 'Full PHP trace',
`event_synced` int(1) unsigned DEFAULT '0',
PRIMARY KEY (`id`),
KEY `event_type` (`event_type`),
KEY `event_source` (`event_source`),
KEY `user_id` (`user_id`),
KEY `server_id` (`server_id`),
KEY `event_date` (`event_date`)
)

Если у кого-нибудь есть идеи по получению таких же результатов без сортировки файлов, это было бы здорово!

Ответы [ 4 ]

4 голосов
/ 24 февраля 2012

GROUP BY подразумевает ORDER BY в MySQL

Поэтому попробуйте добавить ORDER BY NULL: это обычно исключает сортировку файлов

См. "ORDER BY Optimization" в документах MySQL

1 голос
/ 24 февраля 2012

Ваша ключевая проблема в том, что вы указываете не WHERE предложение.Ваше использование WHERE 1=1 бессмысленно.Проблема в том, что вы пытаетесь получить YEAR и MONTH из MySQL без ограничения количества строк, и поэтому он обрабатывает MONTH (..) и YEAR (...) для каждой строки, прежде чем он сможетобработать ГРУППУ.

Тот факт, что он все еще не использует INDEX после моего предыдущего предложения, указывает на то, что у вас больше запросов, чем вы разрешаете, если это так, пожалуйста, дайте мне знать, и я могу помочь вамлегче.В противном случае, я бы порекомендовал проверить ниже (хотя мне нужно угадать ваши цели, так как вы еще не заявили, чего пытаетесь достичь)

Если вы дойдете до последних 6 календарных месяцев, тотакже поможет значительно.

SELECT
    COUNT(id) AS `count`, 
    MONTH(event_date) AS `month`, 
    YEAR(event_date) AS `year`
FROM events
-- Get the first day of this month, and subtract 6 months
WHERE event_date > SUBDATE(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 6 MONTH)
GROUP BY `year` DESC, `month` DESC;

Если у вас есть дополнительные критерии WHERE, это изменило бы приведенный совет, поэтому в таком случае обновите

0 голосов
/ 01 марта 2012
  1. Вы используете SELECT *, что означает выбор всех строк для сканирования всей таблицы - попробуйте выбрать конкретные строки для отображения

  2. Также нет параметров для фильтрации данных, поэтому вся таблица считывается и возвращается, попробуйте ограничить либо датой, либо каким-либо другим параметром

0 голосов
/ 25 февраля 2012

В дополнение к тому, что опубликовали другие:

Если вы запускаете EXPLAIN SELECT... и MySQL сообщает, что он не использует индекс для этого запроса (или не тот, который вы хотите), вы можете решить это с помощьюзапрос данных с помощью SELECT... FORCE INDEX....Для получения более подробной информации о синтаксисе этого, смотрите здесь: http://dev.mysql.com/doc/refman/5.6/en/index-hints.html

...