【问题标题】:A large update request at once?一次大的更新请求?
【发布时间】:2017-10-24 12:13:38
【问题描述】:

在我的代码中,我通过 foreach 循环构建了一个 CASE WHEN 语句,以更新一些数据。

问题是我可能会得到一百行甚至更多的语句,我想知道一次使用如此大的更新请求是否安全。我应该把我的请求分成小块吗?

基本上表格的结构如下:

CREATE TABLE 'table_example' (
'id' INT UNSIGNED NOT NULL ,
'attr_1' INT UNSIGNED NOT NULL ,
'attr_2' INT UNSIGNED NOT NULL ,
'attr_3' DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' ,
'attr_4' DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' ,
'attr_5' TINYINT UNSIGNED NOT NULL ,
'attr_6' TINYINT UNSIGNED NOT NULL ,
'attr_7' TINYINT UNSIGNED NOT NULL ,
'attr_8' SMALLINT UNSIGNED NOT NULL ,
'attr_9' VARCHAR(50) NOT NULL ,
'attr_10' SMALLINT UNSIGNED NOT NULL ,
'attr_11' TINYINT(1) UNSIGNED NOT NULL , 
'attr_12' TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
INDEX 'idx_id' ('id' ASC) )
ENGINE = MyISAM DEFAULT CHARSET=utf8;`

创建后,CASE WHEN 语句可能如下所示:

CASE attr_1  
WHEN id = 1 THEN 5  
WHEN id = 2 THEN 8  
... // could be hundreds more lines here  
ELSE attr_1   
END,  
CASE attr_2  
WHEN id = 1 THEN 96   
WHEN id = 2 THEN 45   
...  // could be hundreds more lines here  
ELSE attr_2   
END,  
... // and so on for each attribute`  

【问题讨论】:

  • 如果不知道表结构、使用过的存储引擎和使用过的查询,我们就无法回答。
  • 我已经添加了您要求的数据。您现在可以在帖子中查看它。
  • 构建和使用 case 语句似乎不太可能是做任何你想做的事情的正确方法。填写一个由 attr_、id 和 int 三元组组成的表,并对每个连接进行更新。此外,人们一定想知道在 DBMS 中也可以有益地完成多少获取 int 的工作。
  • 那你有什么建议?

标签: mysql bulkupdate


【解决方案1】:

根据我在 MySQL 中的经验,明智的做法是通过字符数限制查询的大小。如果您将查询字符数保持在 10K 左右 - 20K字符或更少,您将获得不俗的效率。同时,您不会冒溢出任何缓冲区的风险。

为什么更大的查询更有效?在 InnoDB 的世界中,这是因为每个查询本质上都是一个事务。逐行完成的批量更新可以每行生成一个事务(一次提交)。这会减慢速度。

另一种提高效率的方法是将更新操作包装在单个事务中:

START TRANSACTION;
UPDATE something SET col='val' WHERE id='id';
UPDATE something SET col='val' WHERE id='id';
UPDATE something SET col='val' WHERE id='id';
COMMIT;

这可以节省时间,因为大部分时间都花在了 COMMIT 上。但是,如果您在事务中放置数十万个操作,它可能会用大量事务淹没您的服务器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-15
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多