sql 优化方面不是很懂
有3个表 用户表 tbl_user 角色表 tbl_player 登陆表 tbl_log_login
一个用户 可以有几个角色 一个角色登陆一次就有一条登陆记录想查某个时间段内 输出结果集 用户id 几个角色 登陆次数SET @date1='2010-10-01 00:00:00';
SET @date2='2010-12-02 00:00:00';
SELECT a.uid,COUNT(*) loginNum,COUNT(DISTINCT b.id) playernum
FROM tbl_user a,tbl_player b,tbl_log_login c
WHERE a.uid=b.uid and a.uid=c.uid and b.id=c.pid
and registerTime>=@date1 and registerTime<@date2
and c.logoutTime>=@date1 and c.logoutTime<@date2
GROUP BY a.uid原查询改了下 这是简单点的 忽略可能出现的错误 大体的都在这了
有3个表 用户表 tbl_user 角色表 tbl_player 登陆表 tbl_log_login
一个用户 可以有几个角色 一个角色登陆一次就有一条登陆记录想查某个时间段内 输出结果集 用户id 几个角色 登陆次数SET @date1='2010-10-01 00:00:00';
SET @date2='2010-12-02 00:00:00';
SELECT a.uid,COUNT(*) loginNum,COUNT(DISTINCT b.id) playernum
FROM tbl_user a,tbl_player b,tbl_log_login c
WHERE a.uid=b.uid and a.uid=c.uid and b.id=c.pid
and registerTime>=@date1 and registerTime<@date2
and c.logoutTime>=@date1 and c.logoutTime<@date2
GROUP BY a.uid原查询改了下 这是简单点的 忽略可能出现的错误 大体的都在这了
解决方案 »
- mysql中 在一张表中删除父类子类也删除 的sql语句 表已建好
- 用replace 插入或更新行,如何返回改行主键或某字段?
- 用myisamchk修复数据表如现如下错误
- mysql-如何獲取已知數據的前後筆資料呢?
- MySql求一语句:
- mysql如何同步主服务器和从服务器。谢谢。
- 求助:mysql5.0 jdbc myeclipse 乱码 jsp servlet
- 请教向另一台机器的MySQL数据库插入记录
- mysql的匹配查询问题@@@@@@@@@@@@@@@@@@@@@@@(送100分,只要问题解决)
- 哪里有mysql windows版本的源代码呀,主要是客户端的?
- "新手"关于数据库表外键、主键、索引的问题
- 统计不同分组下,每天的时间差值。
1 SIMPLE c ALL 1466794 Using where; Using temporary; Using filesort
1 SIMPLE b ref uid uid 107 mmo3_stat.c.uid 1 Using where
1 SIMPLE a ALL registerTime 36468 Using where
registerTime、logoutTime是哪个表的
alter table tbl_log_login add index tmp_index_tbl_log_login (logoutTime); 没想到运行了N久 N次 卡了
alter table tbl_log_login add index tmp_index_uid_log_login (uid,pid,logoutTime);
alter table tbl_user add index tmp_index_uid_user (uid);
(SELECT uid,COUNT(*) loginNum FROM tbl_player
WHERE level=1 GROUP BY uid) d
ON a.uid=d.uid但不知放哪里好? 是把上面那3个表联合的结果集作为一个 表 LEFT JOIN (SELECT uid,COUNT(*) loginNum FROM tbl_player
WHERE level=1 GROUP BY uid) d
这个吗?还是有更简单的 我测试下先
tbl_player(uid)
tbl_log_login(uid,pid,logoutTime)
explain SELECT a.uid,COUNT(*) loginNum,COUNT(DISTINCT b.id) playernum
FROM tbl_user a,tbl_player b,tbl_log_login c
WHERE a.uid=b.uid and a.uid=c.uid and b.id=c.pid
and registerTime>=@date1 and registerTime<@date2
and c.logoutTime>=@date1 and c.logoutTime<@date2
GROUP BY a.uid;show index from tbl_user;
show index from tbl_player;
show index from tbl_log_login;
tbl_player(uid,id)
tbl_log_login(uid,pid,logoutTime)
1 SIMPLE b ref uid,tmp_index_pid uid 107 a.uid 1 Using index
1 SIMPLE c ref tmp_index_uid_log_login tmp_index_uid_log_login 66 a.uid,b.id 6 Using where; Using index
这个是简单的那3个表的联合查询 加过索引
| 1 | PRIMARY | <derived3> | ALL | NULL | NULL | NULL | NULL | 278964 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | a | ref | tmp_index_uid_user | tmp_index_uid_user | 107 | e.uid | 1 | Using where |
| 1 | PRIMARY | b | ref | uid | uid | 107 | e.uid | 1 | Using index |
| 1 | PRIMARY | c | ref | tmp_index_uid_log_login | tmp_index_uid_log_login | 66 | mmo3_stat.a.uid,mmo3_stat.b.id | 6 | Using where |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 776 | |
| 3 | DERIVED | tbl_user | index | NULL | tmp_index_uid_user | 107 | NULL | 381026 | |
| 2 | DERIVED | tbl_player | index | NULL | uid | 107 | NULL | 373686 | Using where 这个是加了 left join 的 貌似有点慢 不知道该SELECT XXX IFNULL(max(c.userAgent),max(a.userAgent)),IFNULL(max(c.version),max(a.version))
FROM tbl_log_login c,tbl_player b,tbl_user a
LEFT JOIN
(SELECT uid,COUNT(distinct id) playernumlevel FROM tbl_player
WHERE level=1 and logoutTime>='2010-11-10' and logoutTime<'2010-11-11' GROUP BY uid) d
ON a.uid=d.uid
LEFT JOIN
(SELECT uid,min(registerTime) registerTime FROM tbl_user GROUP BY uid) e
ON a.uid=e.uid
WHERE a.uid=b.uid and a.uid=c.uid and b.id=c.pid
and e.registerTime>='2010-11-10' and e.registerTime<'2010-11-11'
AND cp='30237' AND left(a.uid,4) in(0401,0402,0403)
GROUP BY a.uid;=============
下面是索引情况
tbl_user 0 PRIMARY 1 zone A 6 BTREE
tbl_user 0 PRIMARY 2 uid A 36000 BTREE
tbl_user 1 registerTime 1 registerTime A 36000 YES BTREE
tbl_user 1 convertTime 1 convertTime A 2 YES BTREE
tbl_user 1 tmp_index_uid_user 1 uid A 36000 BTREE
----------------------
tbl_player 0 PRIMARY 1 zone A 18 BTREE
tbl_player 0 PRIMARY 2 id A 134420 BTREE
tbl_player 0 name 1 name A 134420 BTREE
tbl_player 1 uid 1 uid A 134420 BTREE
tbl_player 1 createDate 1 createDate A 134420 BTREE
tbl_player 1 tmp_index_pid 1 id A 134420 BTREE
--------------------
tbl_log_login 0 PRIMARY 1 zone A BTREE
tbl_log_login 0 PRIMARY 2 id A 1466794 BTREE
tbl_log_login 1 tmp_index_uid_log_login 1 uid A 162977 BTREE
tbl_log_login 1 tmp_index_uid_log_login 2 pid A 244465 BTREE
tbl_log_login 1 tmp_index_uid_log_login 3 logoutTime A 1466794 YES BTREE
这个是简单的那3个表的联合查询 加过索引
| 1 | PRIMARY | <derived3> | ALL | NULL | NULL | NULL | NULL | 278964 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | a | ref | tmp_index_uid_user | tmp_index_uid_user | 107 | e.uid | 1 | Using where |
| 1 | PRIMARY | b | ref | uid | uid | 107 | e.uid | 1 | Using index |
| 1 | PRIMARY | c | ref | tmp_index_uid_log_login | tmp_index_uid_log_login | 66 | mmo3_stat.a.uid,mmo3_stat.b.id | 6 | Using where |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 776 | |
| 3 | DERIVED | tbl_user | index | NULL | tmp_index_uid_user | 107 | NULL | 381026 | |
| 2 | DERIVED | tbl_player | index | NULL | uid | 107 | NULL | 373686 | Using where 这个是加了 left join 的 貌似有点慢 不知道该SELECT XXX IFNULL(max(c.userAgent),max(a.userAgent)),IFNULL(max(c.version),max(a.version))
FROM tbl_log_login c,tbl_player b,tbl_user a
LEFT JOIN
(SELECT uid,COUNT(distinct id) playernumlevel FROM tbl_player
WHERE level=1 and logoutTime>='2010-11-10' and logoutTime<'2010-11-11' GROUP BY uid) d
ON a.uid=d.uid
LEFT JOIN
(SELECT uid,min(registerTime) registerTime FROM tbl_user GROUP BY uid) e
ON a.uid=e.uid
WHERE a.uid=b.uid and a.uid=c.uid and b.id=c.pid
and e.registerTime>='2010-11-10' and e.registerTime<'2010-11-11'
AND cp='30237' AND left(a.uid,4) in(0401,0402,0403)
GROUP BY a.uid;
加个order by null 把using sortfile 取消掉,看看怎么样;