从PHP将CSV文件导入SQLite3

从PHP将CSV文件导入SQLite3,php,csv,sqlite,Php,Csv,Sqlite,要创建SQLite3数据库并从PHP的外部CSV文件中插入值,我运行了: $db=new SQLite3("QNH.sqlite"); $q="CREATE TABLE IF NOT EXISTS QNH(id INTEGER PRIMARY KEY,unixtimeutc INTEGER,stationqnh TEXT)"; $db->exec($q);unset($regel);$id=0; if(($fp=fopen("QNH.csv","r"))!==false) {while

要创建SQLite3数据库并从PHP的外部CSV文件中插入值,我运行了:

$db=new SQLite3("QNH.sqlite");
$q="CREATE TABLE IF NOT EXISTS QNH(id INTEGER PRIMARY KEY,unixtimeutc INTEGER,stationqnh TEXT)";
$db->exec($q);unset($regel);$id=0;
if(($fp=fopen("QNH.csv","r"))!==false)
  {while(($regel=fgetcsv($fp,32,","))!==false)
        {$id++;
         $q="INSERT INTO QNH VALUES('".$id."','".$regel[0]."','".$regel[1]."')";
         $db->exec($q);}}
$v=fclose($fp);$db->close();
它是有效的。。。但是速度太慢了,简直不可思议,而且在比赛结束前就超过了60秒。 在总共要添加的105132条线路中,仅添加了733条线路。 以这种速度,它需要超过143分钟。 房屋署为此大惊小怪。 这显然不是解决问题的办法。 我知道如何在SQLite3命令提示符下创建DB和导入CSV文件,这只需几秒钟,但我需要通过PHP脚本来完成。 我到处找,但找不到任何特定于SQLite3和PHP的内容。
有什么想法吗?

与大多数通用编程语言一样,PHP可以使用或执行带有命令行参数的外部程序。这类似于Python的
subprocess.call()
、R的
os.system()
、Java的
ProcessBuilder()
、Perl的
system()
、C#和VB.NET的
Process.Start()

考虑在.sql文件中运行sqlite csv导入,并在php中调用它:

SQL脚本(另存为import.SQL)

PHP脚本(根据需要调整路径名)

exec(“sqlite3 yourdb.sqlite
与大多数通用编程语言一样,PHP可以使用或执行带有命令行参数的外部程序。这类似于Python的
subprocess.call()
、R的
os.system()
、Java的
ProcessBuilder()
、Perl的
system()
、C#和VB.NET的
Process.Start()

考虑在.sql文件中运行sqlite csv导入,并在php中调用它:

SQL脚本(另存为import.SQL)

PHP脚本(根据需要调整路径名)

exec(“sqlite3 yourdb.sqlite
我实现了shell思想,因为它编码简单,执行速度快:

$sql="shell_commands.qsl";$fp=fopen($sql,"w");
$v="create table QNH(unixtimeutc integer,stationqnh text);\n";
$v.=".separator \",\"\n.import ".$csv." QNH\n.exit";$v=fwrite($fp,$v);
$v=fclose($fp);$v=shell_exec("sqlite3.exe ".$db."<".$sql);
$sql=“shell\u commands.qsl”$fp=fopen($sql,“w”);
$v=“创建表QNH(unixtimeutc整数,stationqnh文本);\n”;
$v.=“.separator\”,\“\n.import”。$csv.“QNH\n.exit”$v=fwrite($fp,$v);

$v=fclose($fp)$v=shell_exec(“sqlite3.exe”。$db.”我实现了shell的想法,因为它编码简单,执行速度快:

$sql="shell_commands.qsl";$fp=fopen($sql,"w");
$v="create table QNH(unixtimeutc integer,stationqnh text);\n";
$v.=".separator \",\"\n.import ".$csv." QNH\n.exit";$v=fwrite($fp,$v);
$v=fclose($fp);$v=shell_exec("sqlite3.exe ".$db."<".$sql);
$sql=“shell_commands.qsl”$fp=fopen($sql,“w”);
$v=“创建表QNH(unixtimeutc整数,stationqnh文本);\n”;
$v.=“.separator\”,\“\n.import”。$csv.“QNH\n.exit”;$v=fwrite($fp,$v);

$v=fclose($fp);$v=shell_exec(“sqlite3.exe”。$db.”我知道已经太迟了,但您是否尝试过使用准备好的语句?下面是一个示例:

$elements=file('elements.txt');
$db=new PDO('sqlite:elements.sqlite');
$sql='CREATE TABLE IF NOT EXISTS elements(number int primary key,element varchar, symbol varchar, grp varchar)';
$db->exec($sql);
$sql='INSERT INTO elements(element,number,symbol,grp) VALUES(?,?,?,?)';
$prepared=$db->prepare($sql);
$headers=array_shift($elements);
foreach($elements as $element) {
    $element=explode("\t",trim($element));
    $prepared->execute($element);
}
准备好的语句有助于防止SQL注入,但也有助于加快执行速度


准备允许数据库在运行查询之前解释和计划查询。这是一种需要时间的事情,因此您确实希望只执行一次。后续多次执行可以利用这一点。

我知道已经太晚了,但您是否尝试过使用准备好的语句?以下是一个示例:

$elements=file('elements.txt');
$db=new PDO('sqlite:elements.sqlite');
$sql='CREATE TABLE IF NOT EXISTS elements(number int primary key,element varchar, symbol varchar, grp varchar)';
$db->exec($sql);
$sql='INSERT INTO elements(element,number,symbol,grp) VALUES(?,?,?,?)';
$prepared=$db->prepare($sql);
$headers=array_shift($elements);
foreach($elements as $element) {
    $element=explode("\t",trim($element));
    $prepared->execute($element);
}
准备好的语句有助于防止SQL注入,但也有助于加快执行速度


准备允许数据库在运行查询之前解释和计划查询。这是一种需要时间的事情,因此您确实希望只执行一次。后续多次执行可以利用这一点。

您需要使用事务。请参阅

默认情况下,SQLite将每个查询写入磁盘并同步磁盘。您说可以听到磁盘,这意味着这不是SSD。因此,您受到磁盘转速的限制。在5400 RPM时,需要多次访问(创建备份、同步文件系统目录、提交插入行、删除备份、同步文件系统目录)您正在获得预期的性能

资料来源:



对于完整的解决方案,考虑PHP <代码> AlayyCuxBux/Cuth>一行1000行。您将看到至少100X的性能增加。

< p>您需要使用事务。参见

默认情况下,SQLite将每个查询写入磁盘并同步磁盘。您说可以听到磁盘,这意味着这不是SSD。因此,您受到磁盘转速的限制。在5400 RPM时,需要多次访问(创建备份、同步文件系统目录、提交插入行、删除备份、同步文件系统目录)您正在获得预期的性能

资料来源:



对于完整的解决方案,请考虑PHP <代码> ARAYAYCUBS/<代码>一行1000行。您将看到至少100x的性能增加。

“我知道如何创建DB并在SqLITE3命令提示符中导入CSV文件,这在几秒钟内起作用”,您可以从PHPU调用命令提示符,也可以像这样做多个插入:(如果这适用于您的用例)“我知道如何在SQLite3命令提示符下创建DB并导入CSV文件,这只需几秒钟”您可以从phpy调用命令提示符您也可以这样做多次插入:(如果这适用于您的用例)建议的解决方案会引发错误。当创建行以分号结尾时,该解决方案会起作用。模式为“.csv”不是必需的。固定分号。模式可能是未来读者需要的。好奇,append是否运行得更快?@Parfait,请您解释一下PHP脚本,您在哪里传递表名?我可以看到您只提供了数据库名
yourdb.sqlite
@Himanshu-PHP不运行任何SQL,而是调用一个单独的程序sqlite3.exe,即mmand line executable,在特定数据库上运行外部.sql脚本。建议的解决方案会引发错误。当创建行以分号结尾时,该解决方案会起作用。模式为“.csv”不是必需的。固定分号。模式可能是未来读者需要的。好奇,append是否运行得更快?@Parfait,请您解释一下PHP脚本,您在哪里传递表名?我可以看到您只提供了数据库名
yourdb.sqlite
@Himanshu-PHP