【发布时间】:2015-01-22 03:18:57
【问题描述】:
我正在尝试做一个据说非常简单的查询。我有一个带有时间戳的日期时间列的表。
我需要找到所有没有最后 5 分钟时间戳的父表行。如下所述,这可能会逐行更改。我阅读了许多文章,尝试大量更改我的查询,但我的查询仍然没有正确使用索引。
1) 下面显示的访问表可能有不止一行 mon.id。 2) 我需要找到所有在访问表中没有行的 mon.id,在最后一个 mon.duration 分钟内具有 lastaccess_date 日期时间。 3) 访问表可能多于1行,因此需要检查时间戳最新的行的时长逻辑。
表格如下:
mon (parent)
-----------
id,payload,duration
access (child)
---
id,mon_id,lastaccess_date
当前查询是
select id,payload,elapsed,duration from
(SELECT mon.id,payload,TIMESTAMPDIFF(MINUTE, lastaccess_date, NOW()) as elapsed,duration
FROM mon
inner JOIN access_log log on mon.id=log.monitor_id
order by lastaccess_date desc
) as t1
GROUP BY id
having elapsed>duration
我还进行了一些其他查询,但这些查询似乎效率不高。如果我有 100 行,那么这些查询没有使用索引并进行全表扫描。
请建议一个可以使用索引的高效查询。如果需要,如果对这种情况有帮助,我可以稍微调整一下表格设计。
这个查询的mysql解释如下:
编辑:根据评论以及我之前已经尝试过的内容,我什至将查询更改为激烈:
select monitor_id
from access_log
WHERE access_dt not between date_sub(now(),INTERVAL 5 MINUTE) and now()
现在我没有触及 where 子句中的 access_dt DATETIME 列,但它仍在进行全表扫描。在此测试场景中,查询返回 100 行中的 40 行。
现在是解释:
id, select_type, table, type, possible_keys, key, key_len, ref, rows, filtered, Extra
'1', 'SIMPLE', 'access_log', 'ALL', 'access_dt', NULL, NULL, NULL, '100', '100.00', 'Using where'
【问题讨论】:
-
您在 DATETIME 列上使用函数会破坏索引的使用。重铸查询以消除该功能将允许利用索引。
标签: mysql sql performance indexing