【发布时间】:2014-05-01 20:18:47
【问题描述】:
这可能过于本地化,但希望那里可能有一些我根本无法找到的信息。
背景:我们有一个带有两个独立 Java 守护进程的系统;一个创建数据并插入数据库,另一个抓取最新的数据集(不超过 1 小时),然后推送到客户端。
问题:从此表中抓取的数据有时超过 1 小时。时差可以在 2 小时到几个月之间。
当前查询:获取 1 小时数据是一个两步过程。首先,我们通过设置一个随机负数来“保留”一组记录:
UPDATE tracking_records as target
JOIN
(SELECT tracking_records.id, `set`, unit_id, tracking_records.record_time
FROM tracking_records
WHERE `set` IS NULL and record_time > DATE_SUB(NOW(), INTERVAL 1 HOUR)
ORDER BY record_time DESC LIMIT 48) source
ON source.id = target.id
SET target.`set` = -1371504452;
注意:-1371504452 是一个示例值;它是在 Java 中随机生成的。对于每个查询,LIMIT 48 保持不变。
然后我们只需选择包含该随机set 值的列。
这是tracking_records表的结构:
+-------------+---------------------+
| Field | Type |
+-------------+---------------------+
| id | bigint(20) unsigned |
| unit_id | int(11) |
| record_time | datetime |
| latitude | int(11) |
| longitude | int(11) |
| created_at | datetime |
| updated_at | datetime |
| set | int(11) |
+-------------+---------------------+
如您所见,查询应仅匹配 set 列为空且记录时间最多为 1 小时前的记录。
如前所述,我检测到几个小时到几个月的时差(迄今为止我检测到的最早时间是2013-09-23 11:01:08)。考虑到 WHERE 子句的时间限制,这对我来说没有意义。
我们使用的是mysql版本5.5.29-0ubuntu0.12.04.2
问题:我很困惑,我想知道是否存在错误或其他问题会导致时间计算如此剧烈且随机地失败。要么是这样,要么是查询本身存在我根本没有看到的问题。
有没有人观察到这个版本的 MySQL 中时间比较不正确、DATE_SUB() 函数或INTERVAL 计算的问题,这可能解释了我所看到的异常时间?
【问题讨论】:
-
99% 的情况下,当您使用完善的工具时,问题不在于工具,而在于用户。您确定
record_time是DATETIME值而不仅仅是时间(以小时为单位,而不是小时和天、月、年......)?会不会随时更新? -
@Floris 是的,
record_time始终是包含正确日期和时间值的datetime,并按原样输入。我仔细检查以验证。检测这样的问题相当容易。不,在这种情况下,record_time值一旦输入就永远不会改变。任何一个守护进程中都没有其他更新语句。唯一被操纵的列是set列。 -
我想确保在进行选择之前不存在具有随机值的条目。为什么不总是使用相同的值?首先,将所有
1的值设置为0;然后将您需要的记录设置为1。 -
@Floris 是的。你和斯宾塞是对的;这确实是导致问题的随机数。应该意识到的。我们最初确实有一个步骤,其中“旧”
set值被重置为不同的值,但我们在没有意识到后果的情况下将其删除,以尝试调试一些死锁问题。我们将不得不重新实现类似的东西来解决它。感谢您的帮助!
标签: java mysql sql join sql-update