select * 比select column快很多奇怪案例分析

遇到MYSQL傻傻的地方,下面给个案例,大家感受下:

 注意以下两个sql只有select *和select g.id区别。

SQL1:
SELECT
g.id
FROM
table1 g
INNER JOIN table2 l ON concat('订单号:',CONVERT(g.id,char)) = l.info
WHERE LOCATE('付款操作',l.info) AND g.p = 2
LIMIT 100

查询时间:5.28s

SQL2:
SELECT
*
FROM
table1 g
INNER JOIN table2 l ON concat('订单设为付款操作成功 订单号:',CONVERT(g.id,char)) = l.info
WHERE LOCATE('付款操作成功',l.info) AND g.p = 2
LIMIT 100


查询时间:0.21s

注意以下Sending data的sql1比sql2慢,这是不是很诡异!!!!!!!!!!!!!!

SQL1:

 

SQL2:

 

分析下profile的情况:

sql1的Context_voluntary | Context_involuntary | Block_ops_in | Block_ops_out 比sql2的高很多,按理说字段少,处理数据更快啊!这里为什么反而更慢?????

Context_voluntary :这个是主动上下文切换次数

Context_involuntary :这个是被动上下文切换次数

Block_ops_in :这个是阻塞输入操作

Block_ops_out :这个是阻塞输出操作

 

下面说下原因为什么select column比select *慢:

1.select column比select *处理的数据少

2.mysql的select操作使用的是悲观锁

3.cpu对select column的处理速度要快于select *

4.导致cpu处理完一批数据,ops_in 跟不上,而使用悲观锁,cpu不会自旋,等待数据,而是切换到其它任务

5.所以数据量少的上下文切换的更频繁

6.所以select * 比select column快了很多

 

解决办法:

多加几个字段,增加数据量,这样cpu就没有等待,进行的上下文切换就会少很多,速度就会快很多。如果应用嫌获得数据太多,应用层获得数据把这些数据进行过滤掉就行了。最好的办法是拆分字段,使查询走索引。

SELECT
g.id,g.column1,g.cloumn2
FROM
table1 g
INNER JOIN table2 l ON concat('订单号:',CONVERT(g.id,char)) = l.info
WHERE LOCATE('付款操作',l.info) AND g.p = 2
LIMIT 100

posted on 2018-08-18 18:49  凯特春  阅读(2707)  评论(0编辑  收藏  举报