在过去的6个月里,我试图获得所有访问我们应用程序的用户列表。在我们的表中,我们存储login_time,user_id ..etc。它是一个巨大的表,它将包含300多万行。我们将每个月的表拆分为如下格式的TABLE_MONTH_YEAR。我只在当前月份表中运行此查询。
我试过这个查询。
select max(login_time) , user_id from ZmediaUserDetails group by user_iduser_id是索引列。
login_time是一个时间戳。
我使用主/从设置在生产安装程序中运行此查询。我在从机上运行了这个查询。我等了将近一个小时。但它仍未完成。我使用show slave status检查了从状态,它显示了Seconds_Behind_Master: 4886。所以我就杀了那个问题。
我无法在主或从中创建索引。因为它会锁住整张桌子。
请给出你的建议。
发布于 2013-01-17 08:48:13
您现有的索引根本帮不了您,因为您实际上是在询问每个可能的用户的最后一个时间戳。这意味着MySQL回答这个问题的唯一方法是做一个完整的表扫描。
正如@yper多维数据集所评论的那样,(user_id, login_time)上的索引对于这种查询是很好的-- MySQL可以利用这样的索引,而不需要实际到表中。
向表添加索引确实会锁定表,但也有解决方案。看看橡木-在线-更改-桌子或pt-在线-模式更改 (免责声明:我是第一个作者),这两个脚本都允许通过模拟、触发器和增量复制修改在线表。
您还可能希望以一种完全不同的方式解决这个问题:创建一个新表,如
CREATE TABLE last_user_login_time (
user_id INT UNSIGNED PRIMARY KEY,
last_login_time DATETIME
);和
INSERT INTO last_user_login_time
VALUES (the_user_id, NOW())
ON DUPLICATE KEY UPDATE last_login_time=NOW()在任何新登录时都可以访问此表。因此,保持每个用户在任何给定时间上的最后登录时间。这意味着更多的写入(每次登录需要额外的写),但我怀疑这个表应该非常小,而且影响应该很小。当然,阅读它是微不足道的。
https://dba.stackexchange.com/questions/33032
复制相似问题