今天帮同事看一个bug,需求是找到最新的一条记录。
使用的数据库是postgre,版本是14。
现象
实现sql语句抽取关键后如下:
select xxx from xxx
order by a limit 1
原本预期情况是:加上limit 1 之后,结果为:不加上limit的结果的第一条数据。
这样认为原因是:limit 1 是找到一条符合条件的记录后即返回。理所当然认为是第一条返回,预期效果也认为需要是这样。
实际现象:与预期相反,不是第一条数据。
查询官网:https://www.postgresql.org/docs/14/queries-limit.html
上面说,这是因为查询优化器造成的,但是这里没有写为什么能够造成这样,但是MySQL官网对这种情况有更详细的介绍。
于是mysql官网介绍:https://dev.mysql.com/doc/refman/5.7/en/limit-optimization.html
mysql给出的复现官方例子:
上图order by category,category相同的列加上limit前后顺序不一样了。
关闭排序优化选项前后的对比
如下图所示,mysql有一个选项可以关闭这个排序优化。并且给出了一个这种优化的例子,如果去掉这个优化,会导致扫描更多的行,并且使用文件排序。
官方给出的解决方案:
总结
综上所述,这是一个查询优化器做的优化,不要关系这个优化,再order by 其他的唯一键列,来让limit时的顺序固定,即orderby a,a值相同的列的顺序固定按照其他唯一列排序,即可达到要求。