在GROUP BY YEAR&上的MySQL文件。月

时间:2012-02-24 09:42:33

标签: mysql indexing group-by

我有一个大表,用于存储我的Web应用程序的调试信息。问题是该表现在是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 个答案:

答案 0 :(得分:4)

GROUP BY意味着MySQL中的ORDER BY

所以尝试添加ORDER BY NULL:这通常会删除一个filesort

请参阅MySQL文档中的"ORDER BY Optimization"

答案 1 :(得分:1)

您的关键问题是您没有指定WHERE子句。您对WHERE 1=1的使用毫无意义。问题是你试图从MySQL获取YEARMONTH而不限制行数,因此它在每行之前处理MONTH(..)和YEAR(...)它能够处理GROUP。

在我之前的建议之后仍然没有使用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标准,那将改变给出的建议,如果是这样,请更新

答案 2 :(得分:0)

除了其他人发布的内容之外:

如果您运行EXPLAIN SELECT...并且MySQL报告它不使用该查询的索引(或者不使用您想要的索引),则可以通过使用SELECT... FORCE INDEX...查询数据来解决此问题。有关此语法的更多详细信息,请查看此处:http://dev.mysql.com/doc/refman/5.6/en/index-hints.html

答案 3 :(得分:0)

  1. 您正在使用SELECT *,这意味着选择所有行以便扫描整个表格 - 尝试选择要显示的特定行

  2. 此外,没有参数可以过滤数据,因此会读取并返回整个表格,尝试按日期或其他参数进行限制