简体   繁体   English

我如何加快除循环之外的mysql更新

[英]how do i speed up mysql updates other than looping

I have to read 460,000 records from one database and update those records in another database. 我必须从一个数据库中读取460,000条记录,并在另一个数据库中更新这些记录。 Currently, I read all of the records in (select * from...) and then loop through them sending an update command to the second database for each record. 目前,我读取(选择* from ...)中的所有记录,然后遍历它们,向每个记录的第二个数据库发送更新命令。 This process is slower than I hoped and I was wondering if there is a faster way. 这个过程比我希望的慢,我想知道是否有更快的方法。 I match up the records by the one column that is indexed (primary key) in the table. 我通过表中索引的第一列(主键)匹配记录。

Thanks. 谢谢。

我可能会优化获取大小进行读取(如setFetchSize(250)JDBC -批量处理的写入(例如250个记录的批量大小)。

1. USE MULTI QUERY 1.使用多重查询

aha. 啊哈 'another db' means remote database.. in this case you SHOULD reduce number of interaction with remote DB. “另一个数据库”表示远程数据库。在这种情况下,您应该减少与远程数据库的交互次数。 I suggest that use MULTIPLE QUERY . 我建议使用MULTIPLE QUERY eg to execute 1,000 UPDATE at once, 例如一次执行1,000 UPDATE,

$cnt = 1;
for ($row in $rows)
{
    $multi_query .= "UPDATE ..;";

    if ($cnt % 1000 == 0)
    {
        mysql_query($multi_query);
        $cnt = 0;
        $multi_query = "";
    }
    ++$cnt;

}

Normally Multi query feature is disable (for security reason), To use Multi query 通常出于安全原因禁用多查询功能,要使用多查询

2. USE Prepared Statement 2.使用准备好的声明

(When you are already using prepared stmt. skip this) (如果您已经在使用准备好的stmt,请跳过此步骤)

You are running 460K same structured Queries. 您正在运行460K相同的结构化查询。 So If you use PREPARED STATEMENT , you can obtain two advantages. 因此,如果使用PREPARED STATEMENT ,则可以获得两个优点。

  • Reduce query compile time 减少查询编译时间
    • without prepared stmt. 没有准备好的stmt。 All queries are compiled, but just one time with prepared stmt. 所有查询均已编译,但只有准备好的stmt一次。
  • Reduce Network Cost 降低网络成本
    • Assuming each UPDATE query is 100 bytes long, and there are 4 parameters (each is 4 bytes long) 假设每个UPDATE查询的长度为100个字节,并且有4个参数(每个参数为4个字节)
    • without prepare stmt : 100 bytes * 460K = 46M 不准备stmt:100字节* 460K = 46M
    • with prepare stmt : 16 bytes * 460K = 7.3M 使用prepare stmt:16字节* 460K = 7.3M
    • it doesn't reduce dramatically 它不会急剧减少

Here is how to use prepared statement in VB. 这是在VB中使用预处理语句的方法。

I am assuming your "other database" is on a separate server, so can't just be directly joined. 我假设您的“其他数据库”在单独的服务器上,因此不能直接加入。

The key is to have fewer update statements. 关键是要减少更新语句。 It can often be faster to insert your data into a new table like this: 像这样将数据插入新表通常会更快:

create table updatevalues ( id int(11), a int(11), b int(11), c int(11) );
insert into updatevalues (id,a,b,c) values (1,1,2,3),(2,4,5,6),(3,7,8,9),...
update updatevalues u inner join targettable t using (id) set t.a=u.a,t.b=u.b,t.c=u.c;
drop table updatevalues;

(batching the inserts into however many statements you can fit in however big your maximum size is configured at, usually in the megabytes). (将插入分成很多语句,无论您配置的最大大小有多大,通常都可以以兆字节为单位)。

Alternatively, find unique values and update them together: 或者,找到唯一的值并将其一起更新:

update targettable set a=42 where id in (1,3,7);
update targettable set a=97 where id in (2,5);
...
update targettable set b=1 where id in (1,7);
...

What I ended up doing was using a loop to concatenate my queries together. 我最终要做的是使用循环将我的查询连接在一起。 So instead of sending one query at a time, I would send a group at a time separated by semicolons: 因此,我不是一次发送一个查询,而是一次发送一个由分号分隔的组:

update sometable set x=1 where y =2; update sometable set x = 5 where y = 6; etc...

This ended up improving my time by about 40%. 最终使我的时间缩短了约40%。 My update went from 3 min 23 secs to 2 min 1 second. 我的更新时间从3分23秒增加到2分1秒。

But there was a threshold, where concatenating too many together started to slow it down again when the string got too long. 但是有一个阈值,当字符串太长时,连接在一起太多会开始再次降低速度。 So I had to tweak it until I found just the right mix. 因此,我必须对其进行调整,直到找到合适的组合。 It ended up being 100 strings concatenated together that gave the best performance. 最终将100个字符串连接在一起,可以提供最佳性能。

Thanks for the responses. 感谢您的答复。

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

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