Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用MySQL进行大型后台更新_Mysql_Bulkinsert - Fatal编程技术网

使用MySQL进行大型后台更新

使用MySQL进行大型后台更新,mysql,bulkinsert,Mysql,Bulkinsert,我正在构建一个由MySQL支持的web服务,它定期(比如一天两次)缓存和索引来自外部源的数据。更新例程是唯一修改缓存数据的东西;对于服务的其余部分,此数据是只读的。此外,通过对外部源的多个HTTP请求检索数据。请求的数量与检索到的数据量成正比。假设在组合时,数据不能放入内存。我正在努力实现以下目标: START TRANSACTION; INSERT INTO `data`(`row1`, `row2`, `row3`) VALUES ('val1', 'val2', 'val3'); INSE

我正在构建一个由MySQL支持的web服务,它定期(比如一天两次)缓存和索引来自外部源的数据。更新例程是唯一修改缓存数据的东西;对于服务的其余部分,此数据是只读的。此外,通过对外部源的多个HTTP请求检索数据。请求的数量与检索到的数据量成正比。假设在组合时,数据不能放入内存。我正在努力实现以下目标:

START TRANSACTION;
INSERT INTO `data`(`row1`, `row2`, `row3`) VALUES ('val1', 'val2', 'val3');
INSERT INTO `data`(`row1`, `row2`, `row3`) VALUES ('val4', 'val5', 'val6');
UPDATE `data` SET `row2` = 'val7' WHERE `id` = 3;
/* And so on for a very large number of INSERTs and UPDATEs. */
COMMIT;
  • 从服务其余部分的角度来看,更新是原子的。该服务不应提供一半的更新数据
  • 使新数据的批量插入速度相当快。更新和插入不应使用单独的事务,而应在单个事务中运行。最后应该有一个提交
  • 让这些更新尽可能少地中断其余的服务。批量更新不应在更新发生时锁定其他会话,使其无法访问旧数据
  • 我正在使用InnoDB

    假设我有一个名为
    webservice
    的数据库,其中包含一个名为
    data
    的表。第一次更新数据的明显尝试如下:

    START TRANSACTION;
    INSERT INTO `data`(`row1`, `row2`, `row3`) VALUES ('val1', 'val2', 'val3');
    INSERT INTO `data`(`row1`, `row2`, `row3`) VALUES ('val4', 'val5', 'val6');
    UPDATE `data` SET `row2` = 'val7' WHERE `id` = 3;
    /* And so on for a very large number of INSERTs and UPDATEs. */
    COMMIT;
    
    据我所知,这满足1和2,但违反3

    我想到了另一个似乎满足1、2和3的解决方案。这将使用另一个数据库中的“temp”表来插入新数据,然后交换这些表

    START TRANSACTION;
    DROP TABLE IF EXISTS `webservice_temp`.`data`;
    CREATE TABLE `webservice_temp`.`data` LIKE `webservice`.`data`;
    INSERT INTO `webservice_temp`.`data`
      SELECT * from `webservice`.`data`;
    INSERT INTO `data`(`row1`, `row2`, `row3`) VALUES ('val1', 'val2', 'val3');
    /* etc. */
    COMMIT;
    RENAME TABLE `webservice_temp`.`data` TO `webservice`.`data`;
    

    这是解决我问题的好方法吗?

    如果您使用InnoDB,您可以使用第一种方法(并且它将满足所有三个要求),方法是使用
    启动具有一致快照的事务。这允许在启动事务时从原始数据的快照服务正在进行的读取请求

    WITH CONSISTENT SNAPSHOT
    修饰符为能够执行一致性读取的存储引擎启动一致性读取这仅适用于InnoDB。

    一致读取意味着InnoDB使用多版本控制在某个时间点向查询提供数据库的快照。查询会看到在该时间点之前提交的事务所做的更改,而不会看到稍后或未提交的事务所做的更改

    一种读取操作,它使用快照信息基于时间点显示查询结果,而不考虑同时运行的其他事务执行的更改。如果查询的数据已被其他事务更改,则将根据撤消日志的内容重建原始数据。

    是这样吗!我正在使用InnoDB。这似乎是我正在寻找的解决方案。