优化简单 MySQL 查询响应时间

Optimizing simple MySQL query response time

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

我正在尝试找出获利最多的前 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 table 中有 1000 个条目,在 t_logs table 中有 3000 个事务,这个查询在 VDS 上需要 25 秒使用 Apache 和 2GB 内存,或者在我的本地计算机上使用 XAMPP(我有 16GB 内存)需要 9 秒。

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

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

您应该使用 LEFT JOINGROUP 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
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