我的用例:
我有多个脚本以每秒几个插入的顺序插入到表中。我看到性能下降,所以我认为“批量查询”和每分钟左右插入数百行会有性能优势。
问题:
我如何使用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万行,并且有一些索引。
答案 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()实现更快的实现 - 试试吧。