MYSQL order by 排序的一个小问题探究

小问题发现:

select * from `sql` where id=1 order by (select 1 union select 2)     正常返回结果

mysql> select * from `sql` where id=1 order by (select 1 union select 2);
+----+------+
| id | new  |
+----+------+
|  1 | test |
+----+------+
1 row in set

mysql> select * from mysql.user where user=‘root‘ order by (select 1 union select 2);  报错
1242 - Subquery returns more than 1 row

我的理解应该是都会报 Subquery returns more than 1 row 但是从mysql的运行结果来看不是这样的

继续看查询多条结果的情况

mysql> select * from `sql` where id=1 order by (select 1 union select 2);
+----+------+
| id | new  |
+----+------+
|  1 | test |
+----+------+
1 row in set

mysql> select * from `sql` order by (select 1 union select 2);
1242 - Subquery returns more than 1 row
mysql> select * from `sql` where id in(1,2) order by (select 1 union select 2);
1242 - Subquery returns more than 1 row
mysql> select * from `sql` where id in(1,2);
+----+--------------------+
| id | new                |
+----+--------------------+
|  1 | test               |
|  2 | sqlinjection test2 |
+----+--------------------+
2 rows in set

一条结果的时候不报错,多条结果报错。

经过DBA大牛的指点,DBA这样说的:

只要不走全表扫描,通过主键或者唯一索引能够定位到数据,就可以忽略后面的错误排序语法
如果走全表扫描或者查询的数据不止一条,就有排序语法错误

然后让执行

mysql> explain select * from `sql` where id=1;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | sql   | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
1 row in set
mysql> explain select * from `sql` where id=1;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | sql   | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
1 row in set

mysql> explain select * from `sql` where id in (1,2);
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | sql   | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set

mysql> explain select * from `sql`;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | sql   | ALL  | NULL          | NULL | NULL    | NULL |   24 |       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set
mysql> select * from `sql` where id=1 order by (select 1 union select 2);
+----+------+
| id | new  |
+----+------+
|  1 | test |
+----+------+
1 row in set

mysql> select * from `sql` where id in (1,2) order by (select 1 union select 2);
1242 - Subquery returns more than 1 row
mysql> select * from `sql` order by (select 1 union select 2);
1242 - Subquery returns more than 1 row
mysql> 

可以看到 type  为 const 的时候不会报错。

百度到 type 各个值的含义

type=const表示通过索引一次就找到了;
type=all,表示为全表扫描;
type=ref,因为这时认为是多个匹配行,在联合查询中,一般为REF。

然后继续来看表结构

这里id 为主键,那么我们把id主键去掉,在执行上面的语句。

mysql> select * from `sql` where id=1 order by (select 1 union select 2);
1242 - Subquery returns more than 1 row
mysql> explain select * from `sql` where id=1;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | sql   | ALL  | NULL          | NULL | NULL    | NULL |   24 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set

结果就显示了错误。

结论:

type为const,索引一次就能找到结果的查询会自动忽略order by 的排序错误,直接查询到结果。

时间: 2024-12-28 00:20:37

MYSQL order by 排序的一个小问题探究的相关文章

mysql order by 排序的问题

参考博客http://blog.csdn.net/hollboy/article/details/13296601 mysql order by 的排序在今天时候遇到了问题 情景是:将排序的字段设置成varchar类型了,然后排序时候并没有按从大到小的顺序 按照图中的顺序应该是正序,9排在最上边,但是实际上是666排在最上边 解决办法之一 实际情况是先按最左边的开始排序然后在一位一位比下去,这里在写sql时候的解决办法可以是加0,或者前面加上--也可以哦 解决办法之二 将字段类型换成int类型看

MYSQL order by排序与索引关系总结

MySQL InnoDB B-Tree索引使用Tips 这里主要讨论一下InnoDB B-Tree索引的使用,不提设计,只管使用.B-Tree索引主要作用于WHERE和ORDER BY子句.这里讨论的均在MySQL-Server-5.1.42测试 CREATE TABLE `friends` ( `ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `uid`bigint(20) UNSIGNED NOT NULL DEFAULT '0', `fuid`

MySQL order by 排序结果不正确

新建一张测试表: CREATE TABLE `tb1` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `a` decimal(19,2) NOT NULL, `acid` bigint(20) NOT NULL, `prid` bigint(20) NOT NULL, PRIMARY KEY (`id`), KEY `idx_prid` (`prid`), KEY `idx_acid` (`acid`) ) ENGINE=InnoDB AUTO_INCRE

mysql order by排序查询速度问题

SELECT * FROM `assets_message` LEFT JOIN purchase_message ON assets_message.purchase_id = purchase_message.purchase_id WHERE `purchase_type` = 'oassets'AND purchase_message.assets_type = '002' ORDER BY purchase_message.purchase_id,assets_id SELECT *

MySQL中order by排序时,数据存在null咋办

order by排序是最常用的功能,但是排序有时会遇到数据为空null的情况,这样排序就会乱了,这里以MySQL为例,记录我遇到的问题和解决思路. 问题: 网页要实现table的行鼠标拖拽排序,我用AngularJs集成了一个TableDnD开源插件,可以实现,然后在数据库表中增加一个排序字段indexId,但是原来的大量数据是没有排序过的,所以该字段为null. 这样order by时,为null的数据就会排在最前边. 写个测试表模拟一下,如下效果: 解决办法: 最优办法:利用MySQL中的一

MySQL如何利用索引优化ORDER BY排序语句

MySQL索引通常是被用于提高WHERE条件的数据行匹配或者执行联结操作时匹配其它表的数据行的搜索速度. MySQL也能利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作. 通过索引优化来实现MySQL的ORDER BY语句优化: 1.ORDER BY的索引优化.如果一个SQL语句形如:SELECT [column1],[column2],…. FROM [TABLE] ORDER BY [sort];在[sort]这个栏位上建立索引就可以实现利用索引进行order by

输入6个人的成绩放入到一个一维数组中,然后打印出平均分,最后按成绩 从大到小打印。三个功能(输入是一个函数,求平均分是一个函数,排序是一个 函数)都用函数实现,最后在main方法中调用。

/*5.输入6个人的成绩放入到一个一维数组中,然后打印出平均分,最后按成绩从大到小打印.三个功能(输入是一个函数,求平均分是一个函数,排序是一个函数)都用函数实现,最后在main方法中调用.*/ #include <stdio.h> int inputScore(){ int score; scanf("%d",&score); return score;} double avg(int scores[],int length){ int i,score = 0;

java连接mysql的一个小例子

想要用java 连接数据库,需要在classpath中加上jdbc的jar包路径 在eclipse中,Project的properties里面的java build path里面添加引用 连接成功的一个小例子数据库如下如 代码 package query; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; impor

BeX5开发中MySQL视图使用的一个小问题

问题 数据操作中的查询是极端重要的,使用频繁.MySQL数据库中视图概念的存在十分类似于微软Access小型关系数据库中的查询(二级考试重点).视图的存在极大减小了数据表的创建数量,而且还有更为高级的运用技巧.本文介绍在基于起步科技的BeX5平台上使用MySQL数据库中视图时反向生成本体时注意的一个小问题. MySQL数据库中表在BeX5平台开发中对应于"物理表"概念,但是为了增强软件开发中数据层的灵活性(软件需求阶段的实体结构不是一下百分之分确定的:有时需要不断调整),平台引入了本体