下面的一段对话取自于和用户的一段旺旺聊天记录,在征得用户的同意后,放到我的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的内容贴出来
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):
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):
当然
写完发个连接 我去瞧眼啊