【发布时间】:2015-01-02 04:39:38
【问题描述】:
我有一个“事件”表,用于存储有关实验室计算机登录、注销、关机和启动的一些统计数据。
我希望生成的是最后个每个人计算机名所做的操作列表。
这是我的名为 raw 的表的示例:
mysql> select * from raw limit 20;
+--------+--------------+-------+---------------------+
| id | computername | event | timestamp |
+--------+--------------+-------+---------------------+
| 148776 | REF-18 | 1 | 2014-11-05 15:05:29 |
| 148775 | DEC-02 | 3 | 2014-11-05 15:05:19 |
| 148774 | GPS-06 | 3 | 2014-11-05 15:05:18 |
| 148773 | DEC-15 | 3 | 2014-11-05 15:05:16 |
| 148772 | DEC-02 | 1 | 2014-11-05 15:04:33 |
| 148771 | REF-18 | 2 | 2014-11-05 15:04:18 |
| 148770 | REF-09 | 1 | 2014-11-05 15:04:14 |
| 148769 | REF-18 | 4 | 2014-11-05 15:04:02 |
| 148768 | DEC-02 | 2 | 2014-11-05 15:03:39 |
| 148767 | DEC-02 | 4 | 2014-11-05 15:03:24 |
| 148766 | REF-09 | 2 | 2014-11-05 15:03:00 |
| 148765 | DEC-08 | 3 | 2014-11-05 15:02:54 |
| 148764 | REF-09 | 4 | 2014-11-05 15:02:44 |
| 148763 | REF-09 | 3 | 2014-11-05 15:01:31 |
| 148762 | DEC-01 | 1 | 2014-11-05 15:01:13 |
| 148760 | REF-19 | 1 | 2014-11-05 15:00:50 |
| 148761 | DEC-04 | 3 | 2014-11-05 15:00:50 |
| 148759 | REF-18 | 3 | 2014-11-05 15:00:25 |
| 148758 | DEC-36 | 1 | 2014-11-05 15:00:10 |
| 148757 | DEC-01 | 2 | 2014-11-05 15:00:09 |
+--------+--------------+-------+---------------------+
我想出了几个我认为可行的解决方案;
SELECT r1.id, r1.computername, r1.event, r1.timestamp
FROM raw r1
JOIN (SELECT id, computername, event, MAX(timestamp) AS timestamp
FROM raw GROUP BY computername)
AS r2
ON r1.computername = r2.computername
AND r1.timestamp = r2.timestamp
GROUP BY r1.computername;
这似乎可以完成这项工作,但它需要f o r e v e r
SELECT *
FROM (SELECT * from raw order by timestamp desc) row_result
GROUP BY computername;
到目前为止,这花费的时间要少得多,但似乎产生了相同的结果。哪个更好?第二个查询仅仅是对 MySQL 工作方式的hack 吗?我可以优化我的数据,或者以某种方式查询以产生更快更可靠的结果吗?
谢谢!
【问题讨论】:
-
第二个查询只有在您对时间戳非常幸运时才有效。
-
当事情永远不会发生时,发布
EXPLAIN的结果以供您查询,以查看您的查询是如何执行的。这几乎总是缺少索引和无情的表扫描的情况。 -
你应该尝试为诸如此类的问题提供一个 sql fiddle(至少在我看来),以使可能的回答者更容易 - 因为我们中的许多人可能最终还是单独做.
-
适当索引,您的第一个查询应该非常非常快。与第二个查询相比,它具有被记录的优势,虽然这里的一些人很受欢迎,但正如您所猜测的那样,它是一个未记录的黑客攻击。
-
...此外,在子查询中包含 id 和 event 似乎没有任何目的,在外部查询中也包含 GROUP BY 子句
标签: mysql sql query-optimization greatest-n-per-group