优化简单的MySQL查询响应时间

时间:2015-02-18 20:15:15

标签: mysql query-optimization

我在MySQL中有两个表。一个包含用户,另一个包含交易数据。

我正在努力寻找获利最多的前50位用户。

CREATE TABLE IF NOT EXISTS `t_logs` (
  `tid` int(11) NOT NULL AUTO_INCREMENT,
  `userid` int(11) NOT NULL,
  `amount` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`tid`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;


CREATE TABLE IF NOT EXISTS `t_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `login` varchar(100) NOT NULL,
  `name` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

查询:

SELECT *, (SELECT SUM(amount) FROM `t_logs` WHERE userid=u.id LIMIT 0,1) AS profit
FROM `t_users` u
ORDER BY profit DESC
LIMIT 0,50

现在的问题是,如果我在t_users表中有1000个条目,在t_logs表中有3000个事务,那么这个查询在使用Apache和2GB内存的VDS上需要25秒,或者在使用XAMPP的本地计算机上需要9秒(我有16GB的RAM。。

问题是:我还能做些什么来优化这一切吗?也许将表引擎从MyISAM更改为其他内容?或者也许我的查询无效?或者唯一的解决方案是为VDS添加更多RAM。

如果我们尝试添加10000个用户和10000个日志,则查询在VDS上需要250秒。如果我希望拥有超过50000个用户和超过100万个日志,我有哪些选择?

2 个答案:

答案 0 :(得分:1)

您应该使用LEFT JOIN而非GROUP BY而不是子查询,并且您需要t_logs.userid上的索引:

SELECT u.*, SUM(l.amount) AS profit
FROM t_users u
LEFT JOIN t_logs l
  ON l.userid = u.id
GROUP BY u.id
ORDER BY profit DESC
LIMIT 50

答案 1 :(得分:1)

SELECT u.* , p.profit
FROM `t_users` u
LEFT JOIN (
  SELECT userid, SUM(amount) as profit FROM `t_logs` GROUP BY userid) AS p
ON p.userid=u.id 
ORDER BY p.profit DESC
LIMIT 0,50