BUG总结——记一次sql查询未按照想要的次序返回

这个是一次偶然的sql查询导致

例子,当时是这样的,我写了两个sql,如下

1 select id from (select * from cccc_cer limit 200000,10)a;
2 select id from cccc_cer limit 200000,10;
这两个sql我以为会返回同样的结果,实际上则没有。


我当时的理解是1和2都是一样的sql,没有什么区别,但是其实不是这样。

原因是select的时候实际上并不一定是按照主键id排序的,是按照select最快的次序返回(就是想这么返回怎么返回)所以在强排序的时候需要加上 order by XXX


要想返回正确结果,需要这样:
select id from (select * from cp_order limit 200000,10)a order by id;
select id from cp_order order by id limit 200000,10;

这样才会得到相同结果


后记:忘了出处,侵删。

Select 语句如果不加 “Order By”, MySQL会怎么排序呢?

* 不能依赖 MySQL 的默认排序* 如果你想排序,总是加上 Order By* GROUP BY 强加了 Order By,对于 MyISAM 表MySQL Select 默认排序是按照物理存储顺序显示的。

也就是说SELECT * FROM tbl – 会产生“表扫描”。如果表没有删除、替换、更新操作,记录会显示为插入的顺序。InnoDB 表同样的情况,会按主键的顺序排列。但是这是不靠谱的。潜规则。

“Select” 不加 “Order by”时, MySQL 会尝试以尽可能快的方法(MySQL 实际的方法不见得快)返回数据。

由于访问主键、索引大多数情况会快一些(在Cache里)所以返回的数据有可能以主键、索引的顺序输出,这里并不会真的进行排序,主要是由于主键、索引本身就是排序放到内存的,所以连续输出时可能是某种序列。在一些情况下消耗硬盘寻道时间最短的数据会先返回。如果只查询单个表,在特殊的情况下是有规律的。


最后总结“Order By 是要加的”我们对于翻页等逻辑必须默认加上order by排序,而且order by的字段如果有重复值,必须指定第二排序字段,如果第二排序字段还有重复值,那必须指定更多的字段,直到所有的排序字段能够指定唯一顺序。

猜你喜欢

转载自blog.csdn.net/doujinlong1/article/details/80427739
今日推荐