文档章节

绕过mysql的id:32933 BUG 实现order by limit 正常取数据.

齐天大圣小猴子
 齐天大圣小猴子
发布于 2016/11/07 11:27
字数 1928
阅读 14
收藏 0

今天在写分页的时候遇到了一个Mysql的一个BUG,Google了一下发现网上提出这个问题的Blog就俩还都没有给出解决方案,其实mysql官方早在2007年就已经发布了声明。BUG ID:32933;

发现有人给出了解决方案。后经证实此法用途比较少无法满足一些查询需求。

经过本人一番研究已找到解决方案!

如下所示:

mysql> select * from l_school;
+----+--------------------+------+-------+
| id | name               | area | order |
+----+--------------------+------+-------+
|  1 | 中国人民大学       | 北京 |     1 |
|  2 | 北京交通大学       | 北京 |     1 |
|  3 | 北京科技大学       | 北京 |     2 |
|  4 | 北京邮电大学       | 北京 |     1 |
|  5 | 北京林业大学       | 北京 |     1 |
|  6 | 北京理工大学       | 北京 |     2 |
|  7 | 北京航空航天大学   | 北京 |     1 |
|  8 | 首都师范大学       | 北京 |     1 |
|  9 | 中国矿业大学       | 北京 |    12 |
| 10 | 清华大学           | 北京 |     2 |
| 11 | 北京大学           | 北京 |     1 |
| 12 | 中国地质大学       | 北京 |     2 |
| 13 | 中国农业大学       | 北京 |     2 |
| 14 | 我想去你们公司配镜 | 北京 |     1 |
| 15 | 北京外国语大学     | 北京 |     1 |
| 16 | 北京语言大学       | 北京 |     2 |
| 17 | 北京信息科技大学   | 北京 |     2 |
| 18 | 找不到我的学校     | 未知 |     2 |
+----+--------------------+------+-------+
rows in set

现有如上数据需要做一个分页每页显示13条数据要按order列降序排列;

我想肯定有童鞋会这么写

mysql> select * from l_school order by `order` desc limit 0,13;
+----+------------------+------+-------+
| id | name             | area | order |
+----+------------------+------+-------+
|  9 | 中国矿业大学     | 北京 |    12 |
| 16 | 北京语言大学     | 北京 |     2 |
| 12 | 中国地质大学     | 北京 |     2 |
|  6 | 北京理工大学     | 北京 |     2 |
| 13 | 中国农业大学     | 北京 |     2 |
| 18 | 找不到我的学校   | 未知 |     2 |
|  3 | 北京科技大学     | 北京 |     2 |
| 17 | 北京信息科技大学 | 北京 |     2 |
| 10 | 清华大学         | 北京 |     2 |
| 11 | 北京大学         | 北京 |     1 |
|  8 | 首都师范大学     | 北京 |     1 |
|  7 | 北京航空航天大学 | 北京 |     1 |
|  5 | 北京林业大学     | 北京 |     1 |
+----+------------------+------+-------+
rows in set

恩不错完美!......先不要高兴的太早问题马上就出来了!接下来咱们来取剩下的数据!

mysql> select * from l_school order by `order` desc limit 13,13;
+----+------------------+------+-------+
| id | name             | area | order |
+----+------------------+------+-------+
|  4 | 北京邮电大学     | 北京 |     1 |
|  5 | 北京林业大学     | 北京 |     1 |
| 11 | 北京大学         | 北京 |     1 |
|  7 | 北京航空航天大学 | 北京 |     1 |
|  1 | 中国人民大学     | 北京 |     1 |
+----+------------------+------+-------+
rows in set

上面取出13条加上这次的5条正好18条!有的同学可能发下自己这么容易就搞定了而沾沾自喜!其实......好戏来了!

眼尖的同学可能已经发现了上门的数据有问题!来来咱们来对比一下两次的数据吧!

第一次的数据-------
+----+------------------+------+-------+
| id | name             | area | order |
+----+------------------+------+-------+
|  9 | 中国矿业大学     | 北京 |    12 |
| 16 | 北京语言大学     | 北京 |     2 |
| 12 | 中国地质大学     | 北京 |     2 |
|  6 | 北京理工大学     | 北京 |     2 |
| 13 | 中国农业大学     | 北京 |     2 |
| 18 | 找不到我的学校   | 未知 |     2 |
|  3 | 北京科技大学     | 北京 |     2 |
| 17 | 北京信息科技大学 | 北京 |     2 |
| 10 | 清华大学         | 北京 |     2 |
| 11 | 北京大学         | 北京 |     1 |
|  8 | 首都师范大学     | 北京 |     1 |
|  7 | 北京航空航天大学 | 北京 |     1 |
|  5 | 北京林业大学     | 北京 |     1 |
+----+------------------+------+-------+
rows in set
第二次的数据-------
+----+------------------+------+-------+
| id | name             | area | order |
+----+------------------+------+-------+
|  4 | 北京邮电大学     | 北京 |     1 |
|  5 | 北京林业大学     | 北京 |     1 |
| 11 | 北京大学         | 北京 |     1 |
|  7 | 北京航空航天大学 | 北京 |     1 |
|  1 | 中国人民大学     | 北京 |     1 |
+----+----------
眼尖的童鞋可能已经发下问题所在了!
what fuck!
这是什么东东!
咱们附上总表来对比下

咱们先不写limit 咱们直接写排序
mysql> select * from l_school order by `order` desc 
;
+----+--------------------+------+-------+
| id | name               | area | order |
+----+--------------------+------+-------+
|  9 | 中国矿业大学       | 北京 |    12 |
| 18 | 找不到我的学校     | 未知 |     2 |
| 17 | 北京信息科技大学   | 北京 |     2 |
| 16 | 北京语言大学       | 北京 |     2 |
| 13 | 中国农业大学       | 北京 |     2 |
| 12 | 中国地质大学       | 北京 |     2 |
| 10 | 清华大学           | 北京 |     2 |
|  6 | 北京理工大学       | 北京 |     2 |
|  3 | 北京科技大学       | 北京 |     2 |
|  8 | 首都师范大学       | 北京 |     1 |
|  2 | 北京交通大学       | 北京 |     1 |
| 15 | 北京外国语大学     | 北京 |     1 |
| 14 | 我想去你们公司配镜 | 北京 |     1 |
|  4 | 北京邮电大学       | 北京 |     1 |
|  5 | 北京林业大学       | 北京 |     1 |
| 11 | 北京大学           | 北京 |     1 |
|  7 | 北京航空航天大学   | 北京 |     1 |
|  1 | 中国人民大学       | 北京 |     1 |
+----+--------------------+------+-------+
rows in set

按照自己的想象
select * from l_school order by `order` desc limit 0,13;
应该取出的是这样的数据
+----+--------------------+------+-------+
| id | name               | area | order |
+----+--------------------+------+-------+
|  9 | 中国矿业大学       | 北京 |    12 |
| 18 | 找不到我的学校     | 未知 |     2 |
| 17 | 北京信息科技大学   | 北京 |     2 |
| 16 | 北京语言大学       | 北京 |     2 |
| 13 | 中国农业大学       | 北京 |     2 |
| 12 | 中国地质大学       | 北京 |     2 |
| 10 | 清华大学           | 北京 |     2 |
|  6 | 北京理工大学       | 北京 |     2 |
|  3 | 北京科技大学       | 北京 |     2 |
|  8 | 首都师范大学       | 北京 |     1 |
|  2 | 北京交通大学       | 北京 |     1 |
| 15 | 北京外国语大学     | 北京 |     1 |
| 14 | 我想去你们公司配镜 | 北京 |     1 |
+----+--------------------+------+-------+
rows in set
但是事实却是这样的

+----+------------------+------+-------+
| id | name             | area | order |
+----+------------------+------+-------+
|  9 | 中国矿业大学     | 北京 |    12 |
| 16 | 北京语言大学     | 北京 |     2 |
| 12 | 中国地质大学     | 北京 |     2 |
|  6 | 北京理工大学     | 北京 |     2 |
| 13 | 中国农业大学     | 北京 |     2 |
| 18 | 找不到我的学校   | 未知 |     2 |
|  3 | 北京科技大学     | 北京 |     2 |
| 17 | 北京信息科技大学 | 北京 |     2 |
| 10 | 清华大学         | 北京 |     2 |
| 11 | 北京大学         | 北京 |     1 |
|  8 | 首都师范大学     | 北京 |     1 |
|  7 | 北京航空航天大学 | 北京 |     1 |
|  5 | 北京林业大学     | 北京 |     1 |
+----+------------------+------+-------+
rows in set
第一次取出的数据发现和自己想象中的不一样
如果还不死心的话咱们把剩下的数据取出来
+----+------------------+------+-------+
| id | name             | area | order |
+----+------------------+------+-------+
|  4 | 北京邮电大学     | 北京 |     1 |
|  5 | 北京林业大学     | 北京 |     1 |
| 11 | 北京大学         | 北京 |     1 |
|  7 | 北京航空航天大学 | 北京 |     1 |
|  1 | 中国人民大学     | 北京 |     1 |
+----+------------------+------+-------+
rows in set
发下北京大学竟然出来了两次
我想去你们公司配镜却没有显示出来!
what fuck!究竟是为毛会这样、其实这是一个mysql的BUG
http://bugs.mysql.com/bug.php?id=32933
并且这个BUG出现的时间还不短了.
这里给出解决方案!
如下所示把语句改成join自己然后再order by limit 问题就解决了!
mysql> SELECT a.* FROM l_school as a join l_school as b on a.id = b.id ORDER BY a.`order` desc LIMIT 0,13;
+----+--------------------+------+-------+
| id | name               | area | order |
+----+--------------------+------+-------+
|  9 | 中国矿业大学       | 北京 |    12 |
| 18 | 找不到我的学校     | 未知 |     2 |
| 17 | 北京信息科技大学   | 北京 |     2 |
| 16 | 北京语言大学       | 北京 |     2 |
| 13 | 中国农业大学       | 北京 |     2 |
| 12 | 中国地质大学       | 北京 |     2 |
| 10 | 清华大学           | 北京 |     2 |
|  6 | 北京理工大学       | 北京 |     2 |
|  3 | 北京科技大学       | 北京 |     2 |
|  8 | 首都师范大学       | 北京 |     1 |
|  2 | 北京交通大学       | 北京 |     1 |
| 15 | 北京外国语大学     | 北京 |     1 |
| 14 | 我想去你们公司配镜 | 北京 |     1 |
+----+--------------------+------+-------+
rows in set
----------------------------我是可爱的分割线-----------------
mysql> SELECT a.* FROM l_school as a join l_school as b on a.id = b.id ORDER BY a.`order` desc LIMIT 13,13
;
+----+------------------+------+-------+
| id | name             | area | order |
+----+------------------+------+-------+
|  4 | 北京邮电大学     | 北京 |     1 |
|  5 | 北京林业大学     | 北京 |     1 |
| 11 | 北京大学         | 北京 |     1 |
|  7 | 北京航空航天大学 | 北京 |     1 |
|  1 | 中国人民大学     | 北京 |     1 |
+----+------------------+------+-------+
rows in set


瞬间世界都恢复平静了!
BUG就这么搞定了!

本文转载自:http://www.cnblogs.com/dsphper/p/4371968.html

下一篇: php添加水印
齐天大圣小猴子
粉丝 0
博文 41
码字总数 3764
作品 0
武汉
程序员
私信 提问
mysql limit 大偏移的一个可能的优化方法

mysql limit 语句在大数据量时候,limit后的偏移量过大,第一次查询会特别慢,因为mysql默认是开启查询缓存的,所以,对于第二次再次执行大偏移查询不会有影响。 示例:100万的一个表,id做主...

hell0cat
2013/08/08
759
1
MYSQL 分组

标准的分组Mysql,取的分组所有数据:select * from table where id = id group by id order by id desc limit 1,1; 当使用分组取数量时,先取的所有分组,然后取数量:sleect count() from (...

slagga
2016/07/28
32
0
mysql的limit经典用法及优化

用法一 SELECT .* FROM keyword_rank WHERE (advertiserid='59') LIMIT 2 OFFSET 1; 比如这个SQL ,limit后面跟的是2条数据,offset后面是从第1条开始读取。 用法二 SELECT .* FROM keyword......

drewin
2013/09/24
270
3
Mysql中limit的用法详解

Mysql中limit的用法:在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能。 SELECT FROM table LIMIT [offse...

万里虎
2014/12/03
58
0
报表性能优化方案之单数据集分页SQL实现层式报表

1、概述 我们知道,行式引擎按页取数只适用于Oracle,mysql,hsql和sqlserver2008及以上数据库,其他数据库,如access,sqlserver2005,sqlite等必须编写分页SQL。 下面以Access数据库为例介绍...

九月你好123
2015/09/07
66
0

没有更多内容

加载失败,请刷新页面

加载更多

编程作业20190210900169

1编写一个程序,提示用户输入名和姓,然后以“名,姓”的格式打印出来。 #include <stdio.h>#include <stdlib.h> int main(){ char firstName[20]; char lastName[20]; print......

1李嘉焘1
25分钟前
5
0
补码的优点及原理分析

只讨论整数 1.计算机内部为什么没有减法器? 减法运算本身其实就是加法,如x - y即x +(-y),所以只需要将负数成功表示出来并可以参加加法运算,那加法器就可同时实现“+”和“-”的运算。这...

清自以敬
41分钟前
66
0
Docker 可视化管理 portainer

官网安装指南: https://portainer.readthedocs.io/en/latest/deployment.html docker-compose.yml 位置,下载地址:https://downloads.portainer.io/docker-compose.yml...

Moks角木
今天
7
0
Spring Security 实战干货:必须掌握的一些内置 Filter

1. 前言 上一文我们使用 Spring Security 实现了各种登录聚合的场面。其中我们是通过在 UsernamePasswordAuthenticationFilter 之前一个自定义的过滤器实现的。我怎么知道自定义过滤器要加在...

码农小胖哥
今天
9
0
常见分布式事务解决方案

1 微服务的发展 微服务倡导将复杂的单体应用拆分为若干个功能简单、松耦合的服务,这样可以降低开发难度、增强扩展性、便于敏捷开发。当前被越来越多的开发者推崇,很多互联网行业巨头、开源...

asdf08442a
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部