Mysql order by使用建议

背景

order by 怎样使用索引,避免排序 baseMysql 5.7.30

写在前面
本文摘录自 yangyidba 微信公众号,推荐关注他

官方标准介绍

对于select order by语句如何能够利用到索引,官方表述如下:

"The index can also be used even if the ORDER BY does not match the index exactly, 
as long as all of the unused portions of the index and all the extra 
ORDER BY columns are constants in the WHERE clause."

即使ORDER BY语句不能精确匹配(组合)索引列也能使用索引,只要WHERE条件中的所有未使用的索引部分和所有额外的ORDER BY列为常数就行

表结构

CREATE TABLE `tx` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '记录ID',
  `shid` int(11) NOT NULL COMMENT '商店ID',
  `gid` int(11) NOT NULL COMMENT '物品ID',
  `type` tinyint(1) NOT NULL COMMENT '支付方式',
  `price` int(10) NOT NULL COMMENT '物品价格',
  `comment` varchar(200) NOT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniq_shid_gid` (`shid`,`gid`),
  KEY `idx_price` (`price`),
  KEY `idx_type` (`type`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8

使用explain/desc查看执行计划

1.

SELECT * FROM t1 ORDER BY key_part1,key_part2,...;

desc select * from tx order by shid,gid;
 id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |   100.00 | Using filesort |

原因上述sql没有利用到索引排序. type=ALL Extra=Using filesort,因为where字句没有条件,优化器选择全表扫描和内存排序。

select 了无索引列或是没有where过滤

desc select shid,gid from tx order by shid,gid;
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tx    | NULL       | index | NULL          | uniq_shid_gid | 8       | NULL |   24 |   100.00 | Using index |
+----+-------------+-------+------------+-------+--

2.

SELECT * FROM t1 WHERE key_part1 = constant ORDER BY key_part2;

where条件使用组合索引的左前缀等值查询,使用剩余字段进行order by排序。
desc select * from tx where shid=2 order by gid;
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key           | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | tx    | NULL       | ref  | uniq_shid_gid | uniq_shid_gid | 4       | const |    2 |   100.00 | Using index condition |
+----+-------------+-------+------------+------+------
desc select * from tx where shid=2 order by gid desc;
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key           | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | tx    | NULL       | ref  | uniq_shid_gid | uniq_shid_gid | 4       | const |    2 |   100.00 | Using where |
+----+-------------+-------+------------+-

desc select * from tx where shid=0 order by gid desc;
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key           | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | tx    | NULL       | ref  | uniq_shid_gid | uniq_shid_gid | 4       | const |    1 |   100.00 | Using where |
+----+-------------+-------+------------+------+-

where 条件字句可以基于 shid 进行索引查找并且利用(shid,gid)中gid的有序性避免额外的排序工作。我们基于本例解释"即使ORDER BY语句不能精确匹配(组合)索引列也能使用索引,只要WHERE条件中的所有未使用的索引部分和所有额外的ORDER BY列为常数就行。"

该语句的order by gid 并未精确匹配到组合索引(shid,gid),where条件 shid利用了组合索引的最左前缀且为等值常量查询,对order by 而言shid就是额外的字段,没有出现在order by子句中却是组合索引的一部分。这样的条件既可以使用索引来排序。

3.组合索引的最左前缀匹配

UNIQUE KEY `uniq_shid_gid` (`shid`,`gid`) 使用的时候顺序要和索引的顺序一致

 desc select * from tx where gid=2 order by shid desc;        
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |    10.00 | Using where; Using filesort |
+----+-------------+-------+------------+------+-

4.

SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC;

desc select * from tx order by shid desc,gid desc; 
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |   100.00 | Using filesort |
+----+-------------+-------+------------+-----

选择了倒序。该sql不能利用索引的有序性,需要server层进行排序。
(索引倒序也是不行的,不要select *,本例中commen字段无索引)

但是可以使用覆盖索引的特性,select 字段包含索引列覆盖索引列或是id主键是可以用到索引的
其他的二级索引(普通索引)也不能用的索引,需要Using filesort

desc select shid,gid from tx order by shid desc,gid desc; 
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tx    | NULL       | index | NULL          | uniq_shid_gid | 8       | NULL |   24 |   100.00 | Using index |
+----+-------------+-------+------------+-------+

只有id主键可以和覆盖索引一起使用(order by * desc时):
desc select id,shid,gid from tx order by shid desc,gid desc; 
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tx    | NULL       | index | NULL          | uniq_shid_gid | 8       | NULL |   24 |   100.00 | Using index |
+----+-------------+-------+------------+--

其他索引列typr也不能:(覆盖索引列正序也是需要Using filesort)
desc select type,shid,gid from tx order by shid desc,gid desc;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |   100.00 | Using filesort |
+----+-------------+-------+------------+-----

5.

SELECT * FROM t1 WHERE keypart1 = 1 ORDER BY keypart1 DESC, key_part2 DESC;

desc select *  from tx where shid = 4 order by shid desc,gid desc;          
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key           | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | tx    | NULL       | ref  | uniq_shid_gid | uniq_shid_gid | 4       | const |    2 |   100.00 | Using where |
+----+-------------+-------+------------+----

只是order by 字句中包含所有的组合索引列并且where shid=4 可以利用shid的索引定位数据记录,select * 有不在索引里面的字段,所以回表访问组合索引列之外的数据,利用了gid索引的有序性避免了排序工作。

注意等值过滤的列也要符合覆盖索引的最左前缀匹配

desc select *  from tx where gid = 2 order by shid desc,gid desc; 
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |    10.00 | Using where; Using filesort |
+----+-------------+-------+------------+------+-

desc select *  from tx where gid = 2 order by gid ;      
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |    10.00 | Using where |
+----+-------------+-------+------------+-----

6.

SELECT * FROM t1 WHERE key_part1 > constant ORDER BY key_part1 ASC; SELECT * FROM t1 WHERE key_part1 < constant ORDER BY key_part1 DESC;

desc select * from tx where shid>5 order by shid desc;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | uniq_shid_gid | NULL | NULL    | NULL |   24 |    66.67 | Using where; Using filesort |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)

desc select * from tx where shid>13 order by shid desc; 
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | tx    | NULL       | range | uniq_shid_gid | uniq_shid_gid | 4       | NULL |    2 |   100.00 | Using index condition |
+----+-------------+-------+------------+-------+------

表总共24行,其中大于5的有16行,大于13的2行,导致MySQL优化器选择了不同的执行计划。这个测试说明和shid的区分度有关。

7.

SELECT * FROM t1 WHERE key_part1 = constant1 AND key_part2 > constant2 ORDER BY key_part2;

desc select  * from tx where shid=6 and gid>1 order by gid;
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | tx    | NULL       | range | uniq_shid_gid | uniq_shid_gid | 8       | NULL |    3 |   100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

desc select  * from tx where shid>6 and gid>1 order by gid; 
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | uniq_shid_gid | NULL | NULL    | NULL |   24 |    16.66 | Using where; Using filesort |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)

desc select  * from tx where shid>6 and gid=1 order by gid; 
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | uniq_shid_gid | NULL | NULL    | NULL |   24 |     5.00 | Using where |
+----+-------------+-------+------------+--

利用组合索引前缀索引进行ref等值查询,其他字段进行范围查询,order by 非等值的字段。
利用shid=6的进行索引查询记录到了MySQL的ICP特性,无排序操作。
(一般情况下)需要注意的是,覆盖索引遇到等值匹配=,时会继续使用之后的索引列,否则放弃之后的索引列。

不能利用索引排序的分析

1.

order by语句使用了多个不同的索引 SELECT * FROM t1 ORDER BY key1, key2; 如果想使用索引,select 列名要和order by 列名一致(不能desc select gid from tx order by type;) (但是这个覆盖索引可以desc select gid from tx order by shid;)

desc select gid from tx order by type;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |   100.00 | Using filesort |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
1 row in set, 1 warning (0.00 sec)

desc select gid from tx order by shid;
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tx    | NULL       | index | NULL          | uniq_shid_gid | 8       | NULL |   24 |   100.00 | Using index |
+----+-------------+-------+------------+-------

desc select price,type from tx order by price,type;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+----------------+
|  1 | SIMPLE      | tx    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   24 |   100.00 | Using filesort |
+----+-------------+-------+------------+------+--

特例因为所有的辅助索引里面都包含主键id,当where 字段加上order by字段沟通完整的索引时 ,可以避免filesort的。

desc select type,id from tx  order by type,id;
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key      | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | tx    | NULL       | index | NULL          | idx_type | 1       | NULL |   24 |   100.00 | Using index |
+----+-------------+-------+------------+-------+

desc select * from tx where type=1 order by id;
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra                 |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+-----------------------+
|  1 | SIMPLE      | tx    | NULL       | ref  | idx_type      | idx_type | 1       | const |    6 |   100.00 | Using index condition |
+----+-------------+-------+------------+-----

2.

当查询条件使用了与order by不同的其他的索引,且值为常量,但排序字段是另一个联合索引的非连续部分时 SELECT * FROM t1 WHERE key2=constant ORDER BY keypart1, keypart3;

desc select * from tx where type=1 order by gid;
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra                                 |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+---------------------------------------+
|  1 | SIMPLE      | tx    | NULL       | ref  | idx_type      | idx_type | 1       | const |    6 |   100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)

desc select * from tx where type=1 order by shid;
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra                                 |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+---------------------------------------+
|  1 | SIMPLE      | tx    | NULL       | ref  | idx_type      | idx_type | 1       | const |    6 |   100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+------+---------------

3.

order by 语句使用了和组合索引默认不同的排序规则
SELECT * FROM t1 ORDER BY keypart1 DESC, keypart2 ASC; 官方文档中提示使用混合索引排序规则会导致额外排序,其实我们创建索引的时候可以做 (keypart1 DESC, keypart2 ASC)

desc select shid,gid from tx order by shid desc ,gid; 
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-----------------------------+
| id | select_type | table | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra                       |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-----------------------------+
|  1 | SIMPLE      | tx    | NULL       | index | NULL          | uniq_shid_gid | 8       | NULL |   24 |   100.00 | Using index; Using filesort |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec)

 desc select shid,gid from tx order by shid asc ,gid desc;
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-----------------------------+
| id | select_type | table | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra                       |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-----------------------------+
|  1 | SIMPLE      | tx    | NULL       | index | NULL          | uniq_shid_gid | 8       | NULL |   24 |   100.00 | Using index; Using filesort |
+----+-------------+-------+------------+-------+--------

4.

当where 条件中利用的索引与order by 索引不同时,与案例二有相似性。 SELECT * FROM t1 WHERE key2=constant ORDER BY key1;

desc select * from tx where type=1 order by shid;
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra                                 |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+---------------------------------------+
|  1 | SIMPLE      | tx    | NULL       | ref  | idx_type      | idx_type | 1       | const |    6 |   100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)

desc select id,shid from tx where type=1 order by shid; 
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra                                 |
+----+-------------+-------+------------+------+---------------+----------+---------+-------+------+----------+---------------------------------------+
|  1 | SIMPLE      | tx    | NULL       | ref  | idx_type      | idx_type | 1       | const |    6 |   100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+------+-------------

案例的sql 利用了idxtype 索引,但是order 使用了shid,gid 字段,没有包含在idxtype 索引里面,故不能利用idx_type索引排序。

5.

SELECT * FROM t1 ORDER BY ABS(key); SELECT * FROM t1 ORDER BY -key;

order by 的字段使用函数,和在where条件中使用函数索引一样 ,MySQL都无法利用到索引。

 desc select * from tx where shid=1 order by -shid;
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key           | key_len | ref   | rows | filtered | Extra                                 |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+---------------------------------------+
|  1 | SIMPLE      | tx    | NULL       | ref  | uniq_shid_gid | uniq_shid_gid | 4       | const |    1 |   100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)

master [localhost:17261] {msandbox} (test) > desc select * from tx where shid=1 order by shid; 
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key           | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | tx    | NULL       | ref  | uniq_shid_gid | uniq_shid_gid | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+---------------+---------+-------+------+----------+-------

6.

当查询语句是多表连接,并且ORDER BY中的列并不是全部来自第1个用于搜索行的非常量表.(这是EXPLAIN输出中的没有使用const联接类型的第1个表)

出现join的情况下不能利用索引其实有很多种,只要对a的访问不满足上面说的可以利用索引排序的情况都会导致额外的排序动作。但是当where + order 复合要求,order by 有包含了其他表的列就会导致额外的排序动作。

7.

sql中包含的order by 列与group by 列不一致

group by 本身会进行排序的操作,我们可以显示的注让group by不进行额外的排序动作。

desc select ANY_VALUE(id),ANY_VALUE(type) from tx group by shid order by null;
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key           | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------------+---------+------+------+----------+-------+
|  1 | SIMPLE      | tx    | NULL       | index | uniq_shid_gid | uniq_shid_gid | 8       | NULL |   24 |   100.00 | NULL  |
+----+-------------+-------+------------+
sql_mode=only_full_group_by报错

这个错误发生在mysql 5.7 版本及以上版本会出现的问题:
mysql 5.7版本默认的sql配置是:sql_mode="ONLY_FULL_GROUP_BY",这个配置严格执行了"SQL92标准"。
很多从5.6升级到5.7时,为了语法兼容,大部分都会选择调整sql_mode,使其保持跟5.6一致,为了尽量兼容程序。

如果一个字段没有在target list和group by字段中同时出现,或者是聚合函数的值的话,那么这条sql查询是被mysql认为非法的,会报错误。
(select target list=group by字段)

解决办法1使用ANY_VALUE()函数:select ANY_VALUE(id),ANY_VALUE(type) from tx group by shid;                  
解决办法2更改sql_mode

8.

order by的索引使用部分字符串 比如 key idx_name(name(2))

小结

为了提高order by 查询的速度,尽可能的利用索引的有序性进行排序,如果不能利用索引排序的功能,那么我们只能退而求其次优化order by相关的缓存参数

1.增加 sort_buffer_size 大小,建议sort_buffer_size要足够大能够避免磁盘排序和合并排序次数。
2.增加 read_rnd_buffer_size 大小。
3.使用合适的列大小存储具体的内容,比如对于city字段 varchar(20)比varchar(200)能获取更好的性能。
4.将tmpdir 目录指定到os上面有足够空间的具有比较高iops能力的存储上。

原创为 yangyidba公众号,以上为摘录内容

本文说明,主要技术内容来自互联网技术大佬的分享,还有一些自我的加工(仅仅起到注释说明的作用)。如有相关疑问,请留言,将确认之后,执行侵权必删

猜你喜欢

转载自blog.csdn.net/baidu_34007305/article/details/111168315