[英]Efficient way to insert 1000 rows to MySQL with PDO
I have to insert 1000 rows of data per time into MySQL. 我必须每次将1000行数据插入MySQL。 At the moment, I use PDO and for-loop to insert row by row to database.
目前,我使用PDO和for循环逐行插入数据库。 Is there any more efficient way to achieve better performance?
有没有更有效的方法来实现更好的性能? Because I have to set max_execution_time to 5 minutes.
因为我必须将max_execution_time设置为5分钟。
function save()
{
return $query = $this->insert("
INSERT INTO gadata (landing_page, page_title, page_views, visits, visitors, bounce_rate, pageviews_per_visit, time_on_page, avg_time_on_page, day, month, year, hour)
VALUES (:landing_page, :page_title, :page_views, :visits, :visitors, :bounce_rate, :pageviews_per_visit, :time_on_page, :avg_time_on_page, :day, :month, :year, :hour)", $this->data);
}
And 和
protected function insert($sql, array $data) {
$q = $this->_db_handler->prepare($sql);
foreach ($data as $k => $v)
{
$q->bindValue(':' . $k, $v);
}
$q->execute();
}
It is not PDO nor the way you are inserting makes insert so delayed, but innodb engine. 它不是PDO,也不是您插入的方式如此延迟插入,而是innodb引擎。 So you have 3 choices:
因此,您有3个选择:
innodb_flush_log_at_trx_commit
variable to 2, to make innodb use a filecache for writes - it will make your inserts blazingly fast. innodb_flush_log_at_trx_commit
变量设置为2,以使innodb使用文件高速缓存进行写入-这将使您的插入速度非常快。 可能不是最好的解决方案,但是您可以尝试构造一个查询字符串,例如INSERT INTO [table] VALUES (r1c1,r1c2,r1c3),(r2c1,r2c2,r2c3) ...
并执行一个mysql_query
(或者说一个查询几百行),甚至在构建sql查询时,如果不是来自受信任的来源,您甚至可以通过编程方式验证数据。
Parameterized queries by definition trade execution safety against reduced flexibility on the count of data items. 根据定义,参数化查询会牺牲执行安全性,以减少数据项计数的灵活性。
You have at least 2 possibilities to mitigate: 您至少有两种可能性可以缓解:
Something like: 就像是:
$sql="INSERT INTO gadata (landing_page, page_title, page_views, visits, visitors, bounce_rate, pageviews_per_visit, time_on_page, avg_time_on_page, day, month, year, hour) VALUES ";
foreach ($all_data_rows as $data) {
if ($i==0) $value=""; else $value=",";
$sql.=$value."(:landing_page$i, :page_title$i, :page_views$i, :visits$i, :visitors$i, :bounce_rate$i, :pageviews_per_visit$i, :time_on_page$i, :avg_time_on_page$i, :day$i, :month$i, :year$i, :hour$i)";
$i++;
}
$i=0;
$q=$db_handler->prepare($sql);
foreach ($all_data_rows as $data) {
foreach ($data as $k => $v) {
$q->bindValue(":$k$i", $v);
}
$i++;
}
$q->execute();
First create a temporary table of type HEAP
with the same structure as your target table, then insert into it: This will be much faster, as no locking and disk IO happens. 首先创建一个具有与目标表相同结构的
HEAP
类型的临时表,然后将其插入其中:这将更快,因为不会发生锁定和磁盘IO。 Then run 然后跑
INSERT INTO final_table SELECT * FROM temporary_table
If mitigation doesn't suffice, you will need to consider using non-parameterized queries for this use case. 如果缓解措施不足,则需要针对此用例考虑使用非参数化查询。 The usual caveats apply.
通常需要注意的事项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.