【问题标题】:PHP mysqli_multi_query large insert issuePHP mysqli_multi_query 大插入问题
【发布时间】:2011-07-01 13:53:40
【问题描述】:

我尝试了很多方法来尝试插入从文本文件解析的大量数据(200,000 行文本在我的服务器上大约 2 秒内被解析到数组中,所以我知道那部分不是问题)。我正在使用的 mysqli_multi_query 以 5,000 个块的形式发送查询(由于某种原因,如果我想多次使用 multi_query,它拒绝做任何更大的事情)或者如果我将文本文件拆分为 50,000 行,我可以将它们全部插入2秒内一次。如果我这样做,那么它会拒绝运行另一个查询(我确实读过我需要做 while (mysqli_more_results($db) && mysqli_next_result($db)); 以清除结果,我的 5,000 次拆分确实有这个)

50,000 个插入一个在 2 秒内运行,5,000 个插入一个(50,000 行)需要 40 秒,我有点想在 foreach 中创建一个新的 mysqli 连接(用于 50,000 个插入),但它没有'不总是工作......

我想要一些技巧,告诉我如何让我的函数运行得更快,因为当我正在读取的文件可能包含数十万可能数百万行时,插入所有 50,000 行需要 40 秒。

function log2db(){
$db = mysqli_connect(SQLHOST, SQLUSER, SQLPASS, SQLDB);
if($db){
    $qar = logparse("world2.chat", loglen());
    $query = "";
    $i = 0;
    foreach($qar['data'] as $q){
        $i++;
        $uid = $q['uid'];
        $type = $q['type'];
        $chldst = $q['chldst'];
        $time = $q['date'];
        $msg = $q['msg'];
        $query .= "insert into `messages` (`uid`, `type`, `chldst`, `time`, `message`) values ('$uid', '$type', '$chldst', '$time', '$msg');\n";
        if(!($i % 5000)){
            $qquery[] = $query;
            $query = "";
        }
    }
    $qquery[] = $query;
    foreach($qquery as $qq){
        $q = mysqli_multi_query($db, $qq);
        if($q){
            while (mysqli_more_results($db) && mysqli_next_result($db));
        } else {
            mysqli_error($db);
            return false;
        }
    }
    if($qar !== null){
        loglen($qar['filelen']);
    }
    return true;
}
return false;

}

是我想出的(总是有效,但就像我说的很慢),有什么可以改进它的提示吗?

【问题讨论】:

    标签: php mysqli mysqli-multi-query


    【解决方案1】:

    您是否意识到 INSERT INTO 查询可以在一个单个查询中插入多行?

    $parts  = array();
    
    foreach($qar['data'] as $q){
    
        $uid    = $q['uid'];
        $type   = $q['type'];
        $chldst = $q['chldst'];
        $time   = $q['date'];
        $msg    = $q['msg'];
    
        $parts[] = "('$uid', '$type', '$chldst', '$time', '$msg')";
     }
    
    $query  = "INSERT INTO `messages` (`uid`, `type`, `chldst`, `time`, `message`)";
    $query .= "VALUES ".implode(', ', $parts);
    
    mysqli_query($db, $query)
    

    【讨论】:

    • 真的吗?我从来不知道...我必须尝试一下,我确实认为我之前已经看到过但从未尝试过...
    • 非常非常非常感谢!它现在总共在大约 4 秒内完成(日志解析和 sql 插入)。我真的无法感谢你
    • 嘿,虽然这篇文章已经发布了一年多,但我想提醒您注意它包含 SQL 注入漏洞。最好使用准备好的语句或至少使用 $mysqli->real_escape_string() 来清理用户输入。
    猜你喜欢
    • 1970-01-01
    • 2017-06-13
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 2016-11-26
    • 2012-04-28
    • 2020-05-07
    • 1970-01-01
    相关资源
    最近更新 更多