首页 碎碎念 博客 IT博客 音乐 旅途 你(U) 关于
编程语言 服务器 日常 其他
你正在阅读:

Mysql中orderby和limit同时使用的bug

日常
发布时间:2015-01-17

Mysql中orderby和limit同时使用的bug

    看到自己的文档中有一篇Mysql Bug的记录,打开看了一下,发现是上家公司实习的时候记录下来的了,我回忆了一下当时的情景,好像是产品线提出来的,说专区里面的一个视频排序结果不正确,排在第一位的并不是最新的视频,我查看了一下,果然是这样的情况。于是便找到了对应业务的代码,看了一番,看了看,想了想并没有什么不对,于是到后台查看数据,奇怪的事情冒了出来,后台查询的时候排序是正确的,而两处用到的sql查询代码是一样的,当时的感觉就像是身边似乎有诡异的东西,导致了结果的不同,汗都流出来了。

    回忆一下当时的大概sql语句, SELECT * FROM `TABLE` WHERE *** ORDER BY p_time DESC LIMIT 5;就大概是这样的一条语句,其中有些无关紧要的条件没有列出来,这条SQL语句在两处执行的时候返回的结果并不是相同的,我都在怀疑我的智商是不是被压制了没有发现SQL语句的不同之处,这TM的就是一模一样好吗。

    表格中还有一个存储时间的字段,但其实这两个时间在插入数据的时候是同样的值,于是我尝试在“不正常”的那条SQL中添加了一个条件变成 ORDER BY p_time DESC,s_time DESC,一运行,奇迹出现了,返回的居然是正常的数据。脑袋一下子炸开了,为什么查询同样的数据,两处会出现这样的差异了。后来我把LIMIT条件去掉,两处都用原来的SQL语句查询,返回的结果正常,没有缺失,排序也正常.再把LIMIT条件改为LIMIT 100,同样返回的数据也是正常的,直到把LIMIT设置成 5时,两处返回的结果就截然不同了,并没有获得预期的数据。我想,估计就是这个ORDER BY 和 LIMIT条件在搞鬼了。

    于是便在网上GOOGLE了一番,还发现真的有人出现过类似的情况,下面是网上的案例描述,看完之后终于明白了,但这个问题或许只是某些版本的MySQL中才会出现:


我的SQL很简单

我想从一个表中检索所有标题含有“中国”的数据,将它们按id排序,取前5条,所以我写了以下语句

SQL语句1:

select fi_id, fi_url, fi_title
from InfoTable
where fi_title like '%中国%'
order by fi_id desc
limit 5

当我只使用order by时,能够返回13条结果

只使用limit时,能够返回其中的5条结果

但是当我同时使用order by和limit时,却返回0条结果


同时我们还发现,这种情况并不是在所有检索词上都会出现,如把检索词由“中国”换为“足球”等就不会出现这种现象。

在和同事的讨论中,有人提出了以下方法

SQL语句2:

select * from
(select fi_id, fi_url, fi_title
from InfoTable
where fi_title like '%中国%'
order by fi_id desc ) a
limit 5

语句2能够正确的得到5条结果

这给了我们一些启发:语句1和语句2的执行并不相同,所以语句1很可能与我们最初设想不符,所以,我们对语句1进行了以下修改

limit 5 ---> limit 50000

得到SQL语句3:

select fi_id, fi_url, fi_title
from InfoTable
where fi_title like '%中国%'
order by fi_id desc
limit 50000

此SQL语句能够正确得到13条结果

由此我们推测:在同时使用order by和limit时,MySQL进行了某些优化,将语句执行逻辑从"where——order by——limit"变成了"order by——limit——where",导致在某些情况下,同时使用order by和limit会导致查无结果(或结果数量不足)。具体出现问题与否是与表中数据有关的。


具体的案例见http://bbs.chinaunix.net/thread-1276235-1-1.html

MySQL Bug链接地址:http://bugs.mysql.com/bug.php?id=32933


旧站-时光博物馆
OursTime.cn All Right Reserve @2013-2022
粤ICP备15028708号
部分文章来自互联网,如侵犯隐私或版权请联系 610559722(at)qq.com 撤稿