-1

我需要创建一个表并在那里存储一些事件的缓存状态。所以我只需要做两个操作:

1) 插入事件的id、状态以及该记录存储在数据库中的时间;

2)获取具有特定事件ID的最后一条记录。

有几种方法可以获得结果(状态):

方法一:

SELECT status FROM status_log a
WHERE a.event_id = 1
ORDER BY a.update_date DESC
LIMIT 1

方法二:

SELECT status FROM status_log a
WHERE a.update_date = (
  SELECT max(b.update_date) FROM status_log b
  WHERE b.event_id = 1
)  AND a.event_id = 1

所以我有两个问题:

  1. 使用哪个查询
  2. 将哪个字段类型设置为 update_date 字段(整数或时间戳)
4

2 回答 2

1

实际上,您的第二个查询不能解决问题“查找事件 #1 的最大更新日期的记录” - 因为可能有许多不同的事件具有相同的 latest update_date。因此,就语义而言 - 您应该使用第一个查询。(您的编辑后,这是固定的

如果您将按索引创建event_id索引并且此列将具有良好的基数(即WHERE子句将使用该索引过滤足够少的行),则第一个查询将是有效的。然而,这可以通过update_date向索引添加列来改进——但这只有在有很多行相同时才有意义event_id(很多行足以让 MySQL 使用第二个索引部分)——并且在第一个索引部分内再次具有良好的基数。

EXPLAIN但在实践中——我的建议只是一个理论,你必须用语法和你自己对真实数据的测量来弄清楚。

至于数据类型——通常的做法是使用正确的数据类型(即日期时间/时间戳表示时间点)

于 2013-10-10T14:39:39.393 回答
1

使用哪个查询

我相信第一个应该更快。无论如何,只需EXPLAIN对它们运行,您就会发现自己。

您应该使用的索引将是:

ALERT TABLE status_log ADD INDEX(event_id, update_date)

现在...您是否注意到这些查询不等效?第二个将返回具有最大日期的所有 event_id 的所有状态。

将哪个字段类型设置为 update_date 字段(整数或时间戳)

如果您有一个名为的字段update_date,我无法想象为什么 anint会起到同样的作用。改写问题以在datetime或之间进行选择timestamp,则答案符合要求。如果您只想知道数据库中的记录何时更新,请使用时间戳。如果update_date引用您的域模型中的实体,请使用datetime. 您很可能需要对日期执行计算(添加时间、删除时间、提取一个月等),因此使用 unix 时间戳(我认为应该几乎是只写的)将导致额外的计算时间,因为您' 必须将 转换timestamp为 adatetime然后对该结果执行函数。

于 2013-10-10T14:41:28.120 回答