我有一个应用程序,它接收一个大小 16GB (大约 90,00,000行)的数据文件,该文件将被导入MySQL数据库。每次我运行php脚本时,即使数据库位于运行脚本的同一服务器上,我也会在查询期间收到错误'与MySQL服务器的连接。
在互联网上搜索后,我发现当你耗尽一个资源进行数据库会话,,比如内存,而mysql关闭了连接时就会发生这种情况。想法就是交易你是运行时不应尝试插入大量数据。并且您可以通过将更高的值设置为“max_allowed_packet”来解决此问题。我在我的剧本中做到了这一点:
$db->query( 'SET @@global.max_allowed_packet = ' . 1 * 1024 * 1024 * 1024);
但这也不起作用。除非在插入明显更多行之后发生错误。'
现在,我将文件拆分为较小的文件,每个文件包含10,00,000行,然后处理每个文件。但即使分裂也需要相当长的时间。
我不是PHP程序员,也不是以前使用MySQL。这是别人的代码,我必须重构。所以我的知识几乎为零。
我正在使用LOAD DATA LOCAL INFILE
语句来转储数据。是否有任何方法可以通过在每几行之后提交来缩短交易时间?
答案 0 :(得分:2)
您确实需要使用BigDump
交错导入大型和非常大的MySQL Dump(如phpMyAdmin 2.x转储)即使通过具有硬运行时限制的Web服务器和处于安全模式的Web服务器也是如此。
答案 1 :(得分:0)
我编写了自己的转储脚本,基于与BigDump相同的行。这需要三个命令行争论:
<?php
function GetCommaSeparatedValues($row) //Creates a comma separated list of all the column - values in the row
{
$str = '';
$str = '\'' . addslashes(substr($row,0,12)) . '\',' . //addslashes() escapes special characters with a '\'
'\'' . addslashes(substr($row,12,12)) . '\',' .
'\'' . addslashes(substr($row,24,2)) . '\',' .
'\'' . addslashes(substr($row,26,24)) . '\',' .
'\'' . addslashes(substr($row,50,05)) . '\'';
return str;
}
function print_error($err, $linenumber, $pk)
{
echo $err . ' at line number: ' . $linenumber . PHP_EOL;
}
ini_set('display_errors',1);
ini_set('display_startup_errors',1);
error_reporting(E_ERROR); //Report only those errors that are fatal runtime errors
ini_set('memory_limit', '-1'); //Allow script to use maximum available memory
$query="";
$totalqueries=$argv[3]; //Commit after loading how many lines
$linenumber=0;
$currenttotal=0;
$handle = fopen($argv[1], "r"); //File to dump in database
$tablename = $argv[2]; //table name of the db in which to dump file
$con=mysqli_connect("db1","root","N3@k83@rd","pov2013p_pov");
$lno = 0;
$tempquery = 'SET @@global.max_allowed_packet = ' . 1 * 1024 * 1024 * 1024;
mysqli_query($con,$tempquery);
mysqli_autocommit($con,FALSE);
if ($handle)
{
echo `date` . 'Importing file: ' . $argv[1] . PHP_EOL ;
echo 'Commit after every '. $totalqueries . ' lines. ' . PHP_EOL;
echo 'Dumping into table '. $tablename . PHP_EOL . PHP_EOL;
while (($dumpline = fgets($handle)) !== false)
{
$lno++;
if($currenttotal == $totalqueries)
{
echo `date` . 'Commiting at line number: ' . $linenumber . PHP_EOL . PHP_EOL;
mysqli_commit($con);
$currenttotal=0;
if($temp)
{
while(mysqli_next_result($con))
{
if($result = mysqli_store_result($con))
{
while($r = mysqli_fetch_row($result))
{
echo('*');
}
}
}
}
}
$commaseparated = commaseparatedvalues($dumpline);
$query = 'INSERT INTO pov2013p_pov.'.$tablename.' VALUES ('. $commaseparated .');';
mysqli_query($con,$query) or print_error(mysqli_error($con),$lno,substr($dumpline,0,12));
$currenttotal++;
$linenumber++;
}
if($query!='')
{
echo `date` . 'Commiting at line number: ' . $linenumber . PHP_EOL;
mysqli_commit($con);
}
echo `date` . 'Finished Import.' . PHP_EOL;
}
else
{
echo "Cannot open file";
}
?>
答案 2 :(得分:-2)
以下是在命令行中导入的方法,您可以这样导入大文件:
mysql -hyourhostname-uusername -p databasename < yoursqlfile.sql