【问题标题】:MySql: Update with Inner Join on two tables hangsMySql:在两个表上使用 Inner Join 更新挂起
【发布时间】:2014-10-10 01:50:13
【问题描述】:

总结:
我已经尝试过在 mysql 中的两个表上使用内部连接进行更新的不同变体,但对于少量数据,它们都需要数小时。我认为它应该是一个基本的更新,非常容易和快速,但它总是挂起。任何建议如何优化它以更好地执行?

详情:
在表 student_logins 是每个访问的学生的 ip 和 time_of_visit。每个 IP 登录多次。我想按每个 IP首先 登录的顺序为 IP 分配一个排名,并将结果排名(排名编号)添加到 student_logins 表中的每个条目。

示例:
如果这些是示例条目:

10:45 173.99.999.999
10:46 170.99.999.999
10:47 173.99.999.999
10:49 174.99.999.999
10:50 173.99.999.999
10:51 170.99.999.999

然后应该更新表格以显示:
1 10:45 173.99.999.999
2 10:46 170.99.999.999
1 10:47 173.99.999.999
1 10:49 174.99.999.999
3 10:50 173.99.999.999
2 10:51 170.99.999.999

问题:
我能够毫无问题地获得我想要的排名数字,但是即使只有几千行测试行,我尝试更新表格以包含该排名数字也需要数小时。

我尝试直接使用一个临时表来包含排名,但将其加入 student_logins 表以进行更新需要数小时。我尝试为每个步骤创建两个临时表;代码如下,但当我尝试更新/内部连接两个临时表时它也会挂起几个小时。

SET @rank=0;

CREATE TEMPORARY TABLE tmp1 
(this_rank int(11), ip varchar(16), time_visit datetime, visitor_id int(11))
(SELECT @rank:=@rank+1 as this_rank, s.ip, s.time_of_visit as time_visit 
 FROM student_logins s
 order by s.time_of_visit, s.ip);

CREATE TEMPORARY TABLE tmp2 (ip varchar(16), unique_visitor_id int(11))
(SELECT tmp1.ip as ip, MIN(this_rank) as unique_visitor_id    
FROM tmp1 
GROUP BY ip);

UPDATE tmp1
INNER JOIN tmp2 on 
 tmp1.ip = tmp2.ip
SET tmp1.visitor_id = tmp2.unique_visitor_id;

在上面的代码中,它运行快速且正确,直到 UPDATE 语句..然后挂了几个小时。

有什么建议吗?谢谢。

【问题讨论】:

    标签: mysql performance join


    【解决方案1】:

    您需要tmp2(ip) 的索引。实际上,这个索引可能是最好的:

    create index idx_tmp2_ip_uvi on tmp2(ip, unique_visitor_id)
    

    【讨论】:

    • 效果很好,谢谢! (我认为您的代码应该在括号中包含 ip,而不是 id,而我认为只是一个错字)。现在在主表上需要 0.4 秒...谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 2014-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-30
    • 2014-06-07
    • 2015-05-21
    • 1970-01-01
    相关资源
    最近更新 更多