使用 PHP 进行大量 SQLite 插入
我有大约 14000 行逗号分隔值,我试图使用 PHP PDO 将它们插入到 sqlite 表中,如下所示:
<?php
// create a PDO object
$dbh = new PDO('sqlite:mydb.sdb');
$lines = file('/csv/file.txt'); // import lines as array
foreach ($lines as $line) {
$line_array = (','$line); // create an array of comma-separated values in each line
$values = '';
foreach ($line_array as $l) {
$values .= "'$l', ";
}
substr($values,-2,0); // get rid of the last comma and whitespace
$query = "insert into sqlite_table values ($values)"; // plug the value into a query statement
$dbh->query($query); // run the query
}
?>
此查询需要很长时间,并且要不间断地运行它,我必须使用 PHP-CLI。 有没有更好(更快)的方法来做到这一点?
I have about 14000 rows of comma separated values that I am trying to insert into a sqlite table using PHP PDO, like so:
<?php
// create a PDO object
$dbh = new PDO('sqlite:mydb.sdb');
$lines = file('/csv/file.txt'); // import lines as array
foreach ($lines as $line) {
$line_array = (','$line); // create an array of comma-separated values in each line
$values = '';
foreach ($line_array as $l) {
$values .= "'$l', ";
}
substr($values,-2,0); // get rid of the last comma and whitespace
$query = "insert into sqlite_table values ($values)"; // plug the value into a query statement
$dbh->query($query); // run the query
}
?>
This query takes a long time, and to run it without interuption, I would have to use PHP-CLI.
Is there a better (faster) way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
通过将插入包含在单个事务中,您将看到良好的性能增益。如果不这样做,SQLite 会将每个插入视为自己的事务。
You will see a good performance gain by wrapping your inserts in a single transaction. If you don't do this SQLite treats each insert as its own transaction.
在循环之前启动事务并在循环之后提交事务
您的代码现在的工作方式是,它在每次插入时都会启动一个事务
Start a transaction before the loop and commit it after the loop
the way your code is working now, it starts a transaction on every insert
如果您希望提高速度,请使用准备/获取,这样 SQL 引擎就不必每次都解析出文本字符串。
在循环外进行绑定是违反直觉的,但这就是该方法如此快的原因之一,您基本上是在说“使用这些变量中的数据执行此预编译查询”。因此它甚至不需要在内部移动数据。并且您希望避免重新解析查询,如果您使用类似“插入表(名称)值('$name')”之类的内容,这就是问题,每个查询都会将整个文本字符串发送到数据库以重新解析解析。
还有一件事可以加快速度——将整个循环包装在一个事务中,然后在循环完成时提交事务。
If you're looking for a bit more speed, use prepare/fetch, so the SQL engine doesn't have to parse out the text string each time.
It's counter-intuitive that you do the binding outside the loop, but this is one reason why this method is so fast, you're basically saying "Execute this pre-compiled query using data from these variables". So it doesn't even need to move the data around internally. And you want to avoid re-parsing the query, which is the problem if you use something like "insert into table (name) values ('$name')", every query sends the entire text string to the database to be re-parsed.
One more thing to speed it up -- wrap the whole loop in a transaction, then commit the transaction when the loop is finished.
来自 SQLlite 常见问题解答:
我想说最后一段就是你所需要的。
编辑:对此不确定,但我相信使用 sqlite_unbuffered_query() 应该可以解决问题。
From SQLlite FAQ :
I'd say this last paragraph is what you need.
EDIT: No sure about this, but I believe using sqlite_unbuffered_query() should do the trick.