MySQL更新批量更新和循环更新之间的性能

时间:2018-03-21 15:55:25

标签: mysql

我有2个代码执行相同的操作1运行0.3秒和1秒8秒 我有一个有10000个记录器的表,我更新了所有记录 id列也被编入索引 为什么会有这样的时间差,如果他们都这样做呢?

第一个代码(0.3秒):

UPDATE `trades` SET `profit_loss`= rand() WHERE id < 100000

seconod代码(8秒):

    SET @a = 0 ;
    simple_loop: LOOP
       SET @a=@a+1;
       UPDATE trades SET profit_loss = rand() WHERE id = @a ;
       IF @a=10000 THEN
          LEAVE simple_loop;
       END IF;  

END LOOP simple_loop;

2 个答案:

答案 0 :(得分:0)

您在第二个示例中添加循环工作,而不删除第一个示例中需要完成的任何工作。

两个示例都需要行检查,但第二个示例也需要 变量更新。 2.循环退出标准检查

此外,WHERE id = @aIF @a=10000的组合将转换为效率低于WHERE id < 100000的字节码/解析结构。我对此的细节不太了解,但从逻辑上讲,涉及的动态分配越多,转换效率就越低,即使它只是内存位置更新/重写的问题。

答案 1 :(得分:0)

额外的时间与每种情况下搜索的行数有关。我知道你说你的id列是索引的,但逻辑是两种方式:

让我们使用以下类似的例子

UPDATE trades SET profit_loss= rand() WHERE id = 5

调用此方法时,在修改任何内容之前,首先要检查所需的行数,以便找到满足该WHERE条件的行。如果您的搜索列已编制索引,则该搜索效率更高,但仍会检查更多行,而不仅仅是最终修改的行。如果它没有被索引,它将使用游标,从头开始,直到它到达条件会议行。如果您的搜索列是唯一的,它将停止在那里搜索。如果没有,它将继续,直到它耗尽了表(如果数据被索引,则匹配的索引簇)。

现在,如果我们打电话 UPDATE trades SET profit_loss= rand() WHERE id = 6所有先前的搜索工作都被浪费了。无论它是否被索引,它将重复大量相同的搜索。

相比之下,如果我们调用UPDATE trades SET profit_loss= rand() WHERE id < 6,搜索只会发生一次,但包含以前更新的效果。如果它没有被索引,则光标将遍历每个表行一次以进行检查。如果它已编入索引,那么它可能只搜索匹配的群集

无论哪种方式,您都可以看到您在第一个示例中执行的操作是check the table 1 times and modify (0..N) rows。您的第二个示例是check the table N times and modify (0..1) rows each time

此外,我知道它不是您要求的主要部分,但如果您的唯一目标是修改表格中的每条记录,那么您就不需要{{ 1}}条款。 WHERE是合法的语法。

要验证这一点,请运行以下测试:

UPDATE trades SET profit_loss= rand()

然后尝试

UPDATE trades SET profit_loss = rand() WHERE id <= 10

当你比较时间时,你应该看到明显的差异。