我的数据库中有两个表,如下所示:
ElementRef
users表有大约200,000行,sessions表有大约10m行。我试着做一个简单的JOIN,如下所示:
CREATE TABLE `users` (
`id` varchar(10) DEFAULT NULL,
`gender` varchar(9) DEFAULT NULL,
`age` varchar(5) DEFAULT NULL
KEY `id` (`id`)
)
CREATE TABLE `sessions` (
`user_id` varchar(10) DEFAULT NULL,
`time` int(11) DEFAULT NULL,
KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
当我运行此查询时,即使LIMIT设置为1,它也会无休止地运行而没有结果。如果我省略GROUP BY子句,它会立即运行。这里有什么我可能会遗漏的,或者只是会话表太大而无法高效工作?
提前感谢您的帮助!
答案 0 :(得分:0)
首先应该为表添加索引和主键。 建议将users表中的id作为主键,在会话表中添加id列作为主键。您还可以在sessions表的userid列中添加索引。
答案 1 :(得分:0)
在表格上放置适当的索引非常重要,以确保性能。将primarey键放在id和sessions.user_id上的索引上可以大大提高查询运行时间。
另外,对于引用完整性,请考虑使用外键和约束。
如果您的会话数据是临时的(除非您的表充当某种日志并且需要保留数据),请考虑到期/删除不必要的会话条目以最小化该表。是否需要所有10M会话条目?有20万用户,因为他们同时在线,所以活动会话不应超过20万。如果以后需要,您还可以考虑定期将非活动条目移动到另一个表以进行长期存储。例如,这可以在用户结束其会话时立即完成。
话虽如此,一张包含10M条目的表格应该可以正常使用,而且远远没有考虑到#34;太多"在正确建模的数据库上。
答案 2 :(得分:0)
KEY
关键字表示两个表中的user_id都有索引,所以看起来没问题。
LEFT JOIN
通常比INNER JOIN
更耗时。在这种情况下,我建议尝试这样的子查询:
SELECT users.id,
(SELECT SUM(time)
FROM sessions
WHERE users.id = sessions.user_id) AS TotalTime,
FROM users
LIMIT 1;
此外,您可以问自己是否真的需要知道用户5年前花费的会话时间。最好将其限制在固定的时间段内,例如过去6个月的总会话时间。
您需要在sessions
表中添加一列来指定会话的发生时间(日期)。然后你会添加一个过滤器。