【发布时间】:2011-03-01 22:41:08
【问题描述】:
我有一个表 (logs),其中包含以下列(还有其他的,但这些是重要的):
- id (PK, int)
- 时间戳(日期时间)(索引)
- 持续时间(整数)
基本上,这是一次开始,一次结束的事件的记录。该表目前有几十万行。我预计它会增长到数百万。为了加快查询速度,我添加了另一列和预计算值:
- EndTime(日期时间)(索引)
为了计算 EndTime,我将 Duration 中的秒数添加到 Timestamp 字段中。
现在我要做的是运行一个查询,其中结果计算开始 (Timestamp) 和结束时间 (EndTime) 超出某个时间点的行数。然后,我想在较长的时间跨度(例如一年)内每秒运行一次此查询。我还想计算从特定时间点开始到特定时间点结束的行数。
我创建了以下查询:
SELECT
`dates`.`date`,
COUNT(*) AS `total`,
SUM(IF(`dates`.`date`=`logs`.`Timestamp`, 1, 0)) AS `new`,
SUM(IF(`dates`.`date`=`logs`.`EndTime`, 1, 0)) AS `dropped`
FROM
`logs`,
(SELECT
DATE_ADD("2010-04-13 09:45:00", INTERVAL `number` SECOND) AS `date`
FROM numbers LIMIT 120) AS dates
WHERE dates.`date` BETWEEN `logs`.`Timestamp` AND `logs`.`EndTime`
GROUP BY `dates`.`date`;
请注意,数字表仅用于轻松枚举日期范围。它是一个包含一列 number 的表,包含值 1、2、3、4、5 等...
这正是我要找的……一张有 4 列的表格:
- 日期
- total(在当前时间点之外开始和结束的总行数)
- 新的(此时开始的行)
- 已删除(在此时间点结束的行)
问题是,这个查询可能需要很长时间才能执行。要经过 120 秒(如查询所示),大约需要 10 秒。我怀疑这和我得到它的速度一样快,但我想我会在这里问是否有人对提高此查询的性能有任何想法。
任何建议都会很有帮助。感谢您的宝贵时间。
编辑:我在 Timestamp 和 EndTime 上有索引。
EXPLAIN 在我的查询中的输出:
"id";"select_type";"table";"type";"possible_keys";"key";"key_len";"ref";"rows";"Extra"
"1";"PRIMARY";"<derived2>";"ALL";NULL;NULL;NULL;NULL;"120";"Using temporary; Using filesort"
"1";"PRIMARY";"logs";"ALL";"Timestamp,EndTime";NULL;NULL;NULL;"296159";"Range checked for each record (index map: 0x6)"
"2";"DERIVED";"numbers";"index";NULL;"PRIMARY";"4";NULL;"35546940";"Using index"
当我对我的日志表运行分析时,它显示状态正常。
【问题讨论】:
-
你索引了什么?
EXPLAINing 您的查询的输出是什么?你有analyzedlogs表吗? -
@outis,感谢您的提问。我已将信息添加到帖子底部。
-
分析更多是因为它对查询优化器如何使用索引的影响。现在我很好奇扩展查询计划对您的查询来说是什么,特别是看看查询是否被重写以及如何重写。你会在
EXPLAIN EXTENDED查询之后发布SHOW WARNINGS的结果吗?
标签: mysql