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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM