前言
在本地建了兩張表,一張order表和一張zx表,由於order的使用者id是包含所有我需要的使用者,所以用order作為驅動表left join zx表。
事先我在兩表內都建立了unique的索引(end_date,ownerid),然後用order表 left join zx表。
——按理說應該適用eq_ref的type,結果卻根本沒有用上ownerid的索引,使用強制索引也沒用,但用zx表 left join order表卻能順利用上。
1.重現問題
具體建表就不說了,預設charset=utf8.
截圖如下:
圖1.1
圖1.2
很明顯,這裡有兩個問題:
1.圖1.1中type是ref,ref裡面也只用上了const(常量),並沒有用上o.ownerid;
2.圖1.1中z表遍歷的rows竟然達到56793,事實上這個日期的行數僅有28396行,即使全表也僅是56453行。
這樣,能想見圖1.1執行會有多慢,基本執行不動了。
2.分析和搜尋解決辦法
不說分析了,換著法的改sql也沒用;換著群問大神也沒用;各種搜尋引擎搜才總算有點思路。
關鍵點是「索引用不上的原因可能是字符集不相同」。
於是看了了兩張表的字符集,當然都是utf8;
再看看兩張表這個欄位的字符集:
圖2.1
圖2.2
可以看到,zx表的ownerid莫名變成了utf8_general_ci.
3.解決問題
找到問題那麼更改order表的ownerid的字符集即可:
alter table initial30_order change ownerid ownerid varchar(11) character set utf8 collate utf8_general_ci
圖3.1
再執行一下圖1.1的sql:
圖3.2
ps:如果沒有查詢條件,那麼a left join b,a是驅動表,b是被驅動表,a是全表掃瞄,b是根據條件查詢,如果查不到則返回null.
MySQL left join 避坑指南
這裡我先給出乙個場景,並丟擲兩個問題,如果你都能答對那這篇文章就不用看了。那麼現在有兩個需求 找出每個班級的名稱及其對應的女同學數量 找出一班的同學總數 對於需求1,大多數人不假思索就能想出如下兩種sql寫法 正確 select c.name,count s.name as num from cla...
MYSQl left join聯合查詢效率分析
user表 id name 1 libk 2 zyfon 3 daodao user action表 user id action 1 jump 1 kick 1 jump 2 run 4 swim sql select id,name,action from user as u left join...
MYSQl left join 聯合查詢效率分析
user表 id name 1 libk 2 zyfon 3 daodao user action表 user id action 1 jump 1 kick 1 jump 2 run 4 swim sql select id,name,action from user as u left join...