简体   繁体   English

尝试使用子查询优化简单的SQL更新语句

[英]Trying to optimise a simple SQL update statement with a subquery

This query is very slow, taking about 1 second per record. 该查询非常慢,每条记录大约花费1秒。 Sadly, for (and because of) the size of the database, this is untenable as it will take days to complete. 可悲的是,由于数据库的大小(并且由于数据库的大小),这是站不住脚的,因为要花几天的时间才能完成。

Can you suggest a way to speed it up substantially? 您能否提出一种大幅提高速度的方法? (I only need to run it once, but in a <1hr window ideally) (我只需要运行一次,但最好在<1hr的窗口中运行)

update participants set start_time = (select min(time_stamp)
from tasks where participant_id = participants.participant_id)

I don't think we need full table descriptions to suggest a more sensible query structure, but I can post them if required. 我认为我们不需要完整的表描述来建议更合理的查询结构,但是可以根据需要发布它们。 The database is mysql. 该数据库是mysql。

Many thanks. 非常感谢。

You would need to make sure there is an index on tasks.participant_id. 您需要确保在task.participant_id上有一个索引。 Depending on the number of tasks per participant (if there are really many) you could also add an index on time_stamp, although I don't know if MySQL would make use of it. 根据每个参与者的任务数量(如果真的很多),您也可以在time_stamp上添加一个索引,尽管我不知道MySQL是否会使用它。

You can do it with a temporary table like this: 您可以使用如下临时表来执行此操作:

create temporary table temp 
select id as participant_id, min(time_stamp) as start_time 
from participants inner join tasks on participants.participant_id = tasks.participant_id 
group by participant_id;

update participants, temp 
set start_time = temp.start_time 
where participants.participant_id = temp.participant_id;

This replaces the correlated subquery with a much faster join. 这将以更快的联接替换相关的子查询。

Temporary tables are dropped automatically by the MySQL server when the MySQL connection to the client is closed, so depending on your application's connection handling you might want to drop it manually. 当与客户端的MySQL连接关闭时,MySQL服务器会自动删除临时表,因此您可能需要手动删除临时表,具体取决于应用程序的连接处理。

i think, you don't need an inner select 我认为,您不需要内部选择

update participants set start_time = min(time_stamp)

Correction: 更正:

update participants 
set start_time = min(tasks.time_stamp)
from participants inner join 
tasks on participants.participant_id = tasks.participant_id

and with the correct foreign key and index settings it shouldn't take so long. 并使用正确的外键和索引设置,它不需要花费太长时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM