【问题标题】:How to create only part of queries in transaction with mysqli?如何在使用 mysqli 的事务中只创建部分查询?
【发布时间】:2016-02-25 10:02:40
【问题描述】:

我正在尝试创建一个脚本来将大约 10m 条记录导入 mysql 数据库。

当我使用单个查询进行循环时,导入 2000 条记录需要 20 分钟。

所以我试图通过交易来做到这一点。问题是,在我的循环中,有一些选择查询需要立即触发以获取一些值来创建插入。最后两个查询(插入和更新)可能在事务中。

类似这样的:

foreach($record as $rec) {

   //select sth
   //do sth with result

   //second select sth 
   //do sth with second result

   //prepare values from above results and $rec 

   // below part I'd like to do with transaction

   //insert with new record    
   //update table
}

我知道这有点乱也不准确,但这个函数更复杂,所以我决定只写一个“草稿”,我只需要建议,而不是完整的代码。

问候

【问题讨论】:

    标签: php mysql mysqli transactions


    【解决方案1】:

    事务用于需要被视为一个完全成功或完全失败的单个组的多个语句。听起来您的问题与性能有关,而不是与交易有关。除非有一些您没有包含的信息涉及“必须同时成功”的语句组,否则事务只会分散注意力。

    有几种方法可以解决您的问题,具体取决于您的帖子中没有立即显而易见的一些事情。 - 如果您的 10M 记录的数据源是同一数据库中的一个表,您将使用新记录填充(通过循环结束时的插入和更新),那么您可能能够通过一个单一的数据库查询。 SQL 非常有表现力,通过连接和一些内置函数(SUBSTR()、UPPER()、REVERSE()、CASE...END 等),您可能可以做任何您想做的事情。这将需要阅读 SQL 并尝试根据您可以执行的设置操作来重新构建您的目标。 - 如果您要插入来自数据库外部的记录(例如来自文件),那么我会像这样组织您的代码

    //select sth
    //do sth with result
    
    //second select sth 
    //do sth with second result
    
    //prepare values from above results so that $rec info can be added in later
    
    foreach($record as $rec) {
       //construct a big insert statement
    }
    
    //insert the new records by running the big insert statement   
    //update table
    

    这里的好处是你只用几个查询来访问数据库,而不是每个 $rec 几个查询,所以你的性能会更好(因为数据库调用有开销)。对于 10M 行,您可能需要将上述内容分成几块,因为单个插入的大小是有限制的(请参阅 max_allowed_pa​​cket)。我建议将 10M 分成 5K 或 10K 块,方法是在上面添加另一个循环,将 10M 中的块分开。

    如果您添加了有关您的数据源的详细信息、您想要对数据执行哪些转换、该数据的目的是什么,则可能会给出更清晰的答案

       //select sth
       //do sth with result
    
       //second select sth 
       //do sth with second result
    

    部分是(在稍后如何将信息添加到您的插入语句的上下文中),以及代码的准备值部分的作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-21
      • 1970-01-01
      相关资源
      最近更新 更多