化繁為簡-優化sql

玄慚發表於2016-03-25

下面的一段對話取自於和使用者的一段旺旺聊天記錄,在徵得使用者的同意後,放到我的blog中,希望更多的人能夠看見,分享是一件快樂的事情;同時也想借此來說明一些問題,有時候試圖用一條sql完成所有的業務邏輯可能會遇到麻煩,需要對複雜的sql進行一些拆分,可能會得到更好的效果,好吧,廢話少說,進入正題:

RDS使用者:(17:06:28):
EXPLAIN SELECT COUNT(DISTINCT mobile) AS clientcount , COUNT(aliww) AS aliwwcount , COUNT(DISTINCT email) AS emailcount FROM users_260030441 WHERE sid = 260030441
這sql怎麼優化啊 表中有85W資料
Me~:(17:14:21):
優化這種sql 首先需要會explain 能夠看懂explain的內容 explain的內容貼出來
RDS使用者:(17:16:02):

Me~:(17:16:51):
現在這個查詢走了索引

 

 

RDS使用者:(17:17:05):
但還是慢
Me~:(17:17:17):
但是由於sid = 260030441的記錄達到了 有43w行參與計算 
show index from users_260030441;看看
RDS使用者:(17:18:24):

剛剛我把那三列都加了索引,還是一樣,沒走
Me~:(17:18:47):
不能這樣 那三個索引刪除吧
RDS使用者:(17:19:03):

RDS使用者:(17:20:13):
像這樣的需求,拆分sql查詢也慢
Me~:(17:21:26):
http://hidba.org/?p=389
Me~:(17:22:30):
簡單一點的話:索引調成(sid,mobile,aliww,email)
count(aliww)可以改為count(*)的吧
RDS使用者:(17:23:03):
嗯,
Me~:(17:23:23):
如果可以的話就改成:(sid,mobile,email)
RDS使用者:(17:25:37):
改完後效果:
EXPLAIN SELECT COUNT(DISTINCT mobile) AS clientcount , COUNT(*) AS aliwwcount, COUNT(DISTINCT email) AS emailcount FROM users_260030441 WHERE sid = 260030441;

Me~:(17:28:01):
速度?有提升嗎?
RDS使用者:(17:28:51):
當然,4秒多 還能再快麼
Me~:(17:28:57):
可以
如果在優化極致一點的話:
SELECT COUNT(DISTINCT mobile) AS clientcount , COUNT(*) AS aliwwcount , COUNT(DISTINCT email) AS emailcount
FROM users_260030441 WHERE sid = 260030441;
改為:
—>SELECT COUNT(*) from (select DISTINCT mobile FROM users_260030441 WHERE sid = 260030441 ) t;
SELECT COUNT(*) AS aliwwcount FROM users_260030441 WHERE sid = 260030441
SELECT COUNT(*) from (select DISTINCT email FROM users_260030441 WHERE sid = 260030441) t2
新增兩個索引:
sid+mobile
sid+email
RDS使用者:(17:29:43):
我試試,
Me~:(17:29:49):
效果應該是一樣的吧
RDS使用者:(17:33:00):
這樣挺好
都在1秒內
呵呵
Me~:(17:33:22):
那原來的索引刪除掉
我的那篇blog就有提到過那個優化技術
RDS使用者:(17:35:02):
看到了。我先前用group by 更慢的嘛
Me~:(17:35:35):
http://vdisk.weibo.com/s/2IBpo?t=file

這個是我之前在內部分享的ppt
Me~:(17:37:10):
group by和distinct是一樣的
如果沒有索引 還是會排序的
Me~:(17:39:50):
我可以把這個案例寫到我blog上嗎?
@RDS使用者
RDS使用者:(17:40:07):
當然
寫完發個連線 我去瞧眼啊


相關文章