推荐mysqli批量查询

时间:2013-07-09 04:09:45

标签: php mysql batch-processing

我的用例:

我有多个脚本以每秒几个插入的顺序插入到表中。我看到性能下降,所以我认为“批量查询”和每分钟左右插入数百行会有性能优势。

问题:

我如何使用mysqli进行此操作?我当前的代码使用了一个包装器(pastebin),看起来像是:

$array = array();\\BIG ARRAY OF VALUES (more than 100k rows worth)
foreach($array AS $key => $value){
  $db -> q('INSERT INTO `player_items_attributes` (`column1`, `column2`, `column3`) VALUES (?, ?, ?)', 'iii', $value['test1'], $value['test2'], $value['test3']);
}

备注:

我查看了使用事务,但听起来那些仍会命中服务器,而不是排队。我更喜欢使用包装器(随意建议一个具有与我现有的功能相似的功能),但如果不可能,我会尝试在我使用的包装器中构建建议。

来源:

Wrapper来自here

修改 我正在尝试优化表速度,而不是脚本速度。该表有超过3500万行,并且有一些索引。

1 个答案:

答案 0 :(得分:1)

MySQL INSERT语法允许一个INSERT查询插入多行,如下所示:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

其中每组带括号的值表示表中的另一行。因此,通过处理数组,您可以在一个查询中创建多个行。

有一个主要限制:查询的总大小不得超过配置的限制。对于100k行,您可能不得不将其分解为250行,将您的100k查询减少到400行。您可以更进一步。

我不会尝试对此进行编码 - 您必须编写代码并在您的环境中进行尝试。

这是一个伪代码版本:

escape entire array // array_walk(), real_escape_string()

block_size = 250; // number of rows to insert per query
current_block = 0;
rows_array = [];


while (next-element <= number of rows) {

    create parenthesised set and push to rows_array  // implode()

    if (current_block == block_size) {
        implode rows_array and append to query 
        execute query
        set current_block = 0
        reset rows_array
        reset query
    }
    current_block++
    next_element++
}

if (there are any records left over) {
    implode rows_array and append to query 
    execute the query for the last block
}

我已经可以想到使用array_map()实现更快的实现 - 试试吧。