简体   繁体   中英

MySQL inconsistent date ordering

I've encountered a curious problem while debugging a failing integration test. I seem to get inconsistent results depending on the sort direction ( ASC / DESC ) of the following query:

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

The above query returns these results, which is as I would expect:

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

However, if I switch the sort order from ASC to DESC , I get this:

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

It's as if MySQL is unable to distinguish the difference between the dates with more than second accuracy when the query is in descending order.

If I change the dates so that there is a 1 second gap between each last_updated value, then the ordering works correctly in both directions.

These queries are being executed via a Grails / Hibernate based application. If I add some debug code in my application, I can see that the dates are all different and accurate to 1 ms:

1436989535410, 1436989535646, 1436989534516, 1436989534990, 1436989534751

So the data is being stored to a sufficient precision...

User table declaration looks like this:

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

I'm using MySQL 5.6.15.

The same query / integration test works correctly when tested with the H2 Java in-memory database.

EDIT:

Interestingly, it does look like some precision is being lost. If I run the following query:

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;

I get this:

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

I guess Hibernate is caching the more precise pre-persistence date values and giving them back to me when I try to debug in my application...

Try to change the last_updated field to DATETIME(6) instead of DATETIME . This way you can get microsecond resolution. MySQL Reference.

You might add the id field as denominator of equal seconds as inserts are atomar (first come fist serve)

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

resp.

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

SQL fiddle here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM