我的用例:
我有多个脚本以每秒几次插入的顺序插入到表中。我发现性能下降,因此我认为“批处理查询”和每分钟左右插入数百行会带来性能优势。
问题:
我该如何使用 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']);
}
注释:
我研究过使用事务,但听起来那些事务仍然会到达服务器,而不是排队。我更喜欢使用包装器(请随意建议一个与我当前提供的功能类似的包装器),但如果不可能,我会尝试将建议构建到我使用的包装器中。
来源:
包装来自here
编辑: 我正在尝试优化表速度,而不是脚本速度。该表有超过 3500 万行,并且有一些索引。
最佳答案
MySQL INSERT
语法允许一个 INSERT
查询插入多行,如下所示:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
其中每组括号内的值代表表中的另一行。因此,通过处理数组,您可以在一个查询中创建多行。
有一个主要限制:查询的总大小不得超过配置的限制。对于 100k 行,您可能必须将其分解为 250 行等 block ,从而将 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() 可能更快的实现 - 尝试一下。
关于php - mysqli批量查询推荐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17539742/