MySQL不一致的日期排序

时间:2015-07-15 19:57:46

标签: mysql hibernate grails

我在调试失败的集成测试时遇到了一个奇怪的问题。我似乎得到了不一致的结果,具体取决于以下查询的排序方向(ASC / DESC):

SELECT u.id, u.last_updated FROM user u WHERE u.id IN (36, 37, 38, 39, 40) ORDER BY u.last_updated ASC;

以上查询返回这些结果,正如我所料:

id  last_updated
=======================
36  2015-07-15 19:45:34
37  2015-07-15 19:45:34
38  2015-07-15 19:45:34
39  2015-07-15 19:45:35
40  2015-07-15 19:45:35

但是,如果我将排序顺序从ASC切换到DESC,我就明白了:

id  last_updated
=======================
39  2015-07-15 19:45:35
40  2015-07-15 19:45:35
36  2015-07-15 19:45:34
37  2015-07-15 19:45:34
38  2015-07-15 19:45:34

当查询按降序排列时,就好像MySQL无法区分日期之间的差异超过第二精度。

如果我更改日期以便每个last_updated值之间有1秒的间隔,那么排序在两个方向上都能正常工作。

这些查询是通过基于Grails / Hibernate的应用程序执行的。如果我在我的应用程序中添加一些调试代码,我可以看到日期都是不同的,精确到1毫秒:

1436989535410, 1436989535646, 1436989534516, 1436989534990, 1436989534751

所以数据存储到足够的精度......

用户表声明如下所示:

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `last_updated` datetime NOT NULL,
  ...
)

我正在使用MySQL 5.6.15。

使用H2 Java内存数据库进行测试时,相同的查询/集成测试正常工作。

修改

有趣的是,它确实看起来有些精确度正在丢失。如果我运行以下查询:

SELECT u.id, u.last_updated, UNIX_TIMESTAMP(u.last_updated) FROM user u WHERE u.id IN (36, 37, 38, 39, 40) ORDER BY u.last_updated ASC;

我明白了:

id  last_updated         unix timestamp
=======================================
36  2015-07-15 19:45:34  1436985934
37  2015-07-15 19:45:34  1436985934
38  2015-07-15 19:45:34  1436985934
39  2015-07-15 19:45:35  1436985935
40  2015-07-15 19:45:35  1436985935

我想Hibernate正在缓存更精确的预持久性日期值,并在我尝试在我的应用程序中调试时将它们还给我...

2 个答案:

答案 0 :(得分:2)

尝试将last_updated字段更改为DATETIME(6)而不是DATETIME。这样您就可以获得微秒级的分辨率。 MySQL Reference.

答案 1 :(得分:0)

您可以将id字段添加为相等秒的分母,因为插入是atomar(先到先发服务)

 ... 40) ORDER BY u.last_updated ASC, id ASC;

RESP。

 ... 40) ORDER BY u.last_updated DESC, id DESC;

SQL fiddle here