同样的sql,mysql 每次查询结果顺序不一致

  最近在项目遇到了一个问题就是,一个列表中排序的字段比较多,并且有个导出功能,因为导出的 内容给别字段和列表中不一致啊,并且要求全部 导出,没有分页,所以我没有和列表公用一个数据源方法,在测试的时候发现了一个bug,就是我导出的内容和列表中的内容的顺序不一样,这让我很意外,然后我多次测试以后发现,我在列表中调整分页大小的时候也会影响排序效果,这就比较尴尬了。开始我想怎么分页大小还影响排序效果了呢?mysql的执行顺序是先执行排序在分页的,所以这种猜测不对,查了些资料,发现是排序字段中有相同内容的时候,mysql每次都随机取一个,这就可能导致每次取出来的顺序不一致,但是为什么同样的sql在mysql 客户端执行没有我问题呢?查询了很多资料,也没找到一个比较确认的理由,只是较多人认为是由于缓存的存在。

一些比较官方的解释:

根数据库系统的算法有关,早期版本的算法是自然的多个线程二分法,那个线程先查到满足条件的数据就先输出出来,这样就是乱序的,后期经过改进按照主键自然排序输出。如果order by的值相同,一般是按自然排序,就是首个字符的字母或汉字的发音的首字母的s排序。

order by的字段自然排序,如果你的order by 字段是resort,resort值相同的情况下,是可能有两种结果,一种就是你列出的随机排序,还有一种就是按主键来排序。这个问题不是固定的,还可能跟你的服务器性能都有关系,如果内存足够大,执行mysql的时候会提供足够大的缓冲池,也可能会出现另一种结果。

 所以很有可能是因为缓存的存在,在mysql客户端存在缓存,然后每一次查询都走缓存所以他的顺序不会发生改变。然而执行java程序顺序不一致,可能就是因为没有走缓存,每一次都是实时查询。也许java程序的这种结果本身就具有更多的可靠性。

那么我们怎么解决这个问题呢?

很简单,他不是顺序有时会不一致吗,那我们再给他一个顺序进行排序就好了。在order by 后面加上 id desc  , 那么我们的查询结果就是一致了的。

 

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
您好!对于您提到的问题,JdbcTemplate.queryForList()方法返回的结果是一个List,其中包含了查询结果的每一行数据,但是并不保证返回结果的顺序SQL查询顺序一致。 在使用JdbcTemplate进行查询时,数据库返回的数据可能会被JdbcTemplate进行一定的优化或重新排序,导致返回结果的顺序SQL查询顺序一致。这可能是由于数据库内部对数据进行了优化或者使用了索引等技术进行了数据重排。 如果您需要确保返回结果的顺序SQL查询顺序一致,您可以考虑使用JdbcTemplate.query()方法,该方法返回一个List,其中包含了查询结果的每一行数据,并且保持了查询结果的顺序SQL查询顺序一致。 示例代码如下所示: ``` List<Map<String, Object>> resultList = jdbcTemplate.query(sql, new RowMapper<Map<String, Object>>() { @Override public Map<String, Object> mapRow(ResultSet rs, int rowNum) throws SQLException { Map<String, Object> rowMap = new LinkedHashMap<>(); ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); for (int i = 1; i <= columnCount; i++) { String columnName = metaData.getColumnName(i); Object columnValue = rs.getObject(i); rowMap.put(columnName, columnValue); } return rowMap; } }); ``` 在上述示例代码中,我们使用了JdbcTemplate.query()方法,并自定义了一个RowMapper来处理查询结果中的每一行数据,并将其存储在一个有序的Map中。 希望能够帮助到您!如有更多问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

g-Jack

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值