如果值位于由另一个表组成的数组中,如何使用PHP和PDO在MySQL中更快地插入多行(~70k)?
我试图将多行插入到一个被截断的表中,而这个过程需要很长时间才能完成。大约有800行,我需要60多秒才能完成,考虑到我必须对一个有70k行的表执行相同的过程,这已经是个问题了(我做了计算,大概需要1小时45分钟才能完成)。代码如下:如果值位于由另一个表组成的数组中,如何使用PHP和PDO在MySQL中更快地插入多行(~70k)?,php,mysql,sql,Php,Mysql,Sql,我试图将多行插入到一个被截断的表中,而这个过程需要很长时间才能完成。大约有800行,我需要60多秒才能完成,考虑到我必须对一个有70k行的表执行相同的过程,这已经是个问题了(我做了计算,大概需要1小时45分钟才能完成)。代码如下: set_time_limit(5000); //bypass 30s limit $serverName = "<servername>"; $connectionInfo_mssql = array("Database"=>"<dbnam
set_time_limit(5000); //bypass 30s limit
$serverName = "<servername>";
$connectionInfo_mssql = array("Database"=>"<dbname>", "CharacterSet"=>"UTF-8");
try
{
$conn_mssql = new PDO("sqlsrv:Server=$serverName;Database=<dbname>");
$conn_mssql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn_mysql = new PDO("mysql:host=localhost;dbname=<dbname>", "<user>", "<pass>");
$conn_mysql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//SELECT FROM SQL SERVER DB
$mssql_array = array();
$mssql_query = $conn_mssql->prepare("SELECT * FROM Awards");
$mssql_query->execute();
while($row = $mssql_query->fetch(PDO::FETCH_BOTH))
{
$mssql_array[] = array('id' => $row['id'],
'IDNO' => $row["IDNO"],
'title' => $row['title'],
'place' => $row['place'],
'awarded' => $row['awarded'],
'datee' => $row['datee']);
}
//empties out the MySQL Table
$mysql_query = $conn_mysql->prepare("TRUNCATE TABLE Awards");
$mysql_query->execute();
if($mysql_query)
{
echo "Truncate Success"."<br>";
}
else
{
echo "Truncate Error";
}
//inserts values from SQL Server DB to the empty MySQL Table
$sql = $conn_mysql->prepare("INSERT INTO Awards VALUES (:id, :IDNO, :title, :place, :awarded, :datee)");
foreach($mssql_array as $key => $value)
{
$params_insert = array(':id' => $value['id'],
':IDNO' => $value['IDNO'],
':title' => $value['title'],
':place' => $value['place'],
':awarded' => $value['awarded'],
':datee' => $value['datee']);
$sql->execute($params_insert);
}
echo 'Table Awards from MS SQL DB and table Awards from MySQL DB are now synced!'."<br>";
echo "<a href='table_updater.php'>Go back to updater</a>";
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
?>
设置时间限制(5000)//旁路30秒限制
$serverName=“”;
$connectionInfo_mssql=array(“数据库”=>,“字符集”=>“UTF-8”);
尝试
{
$conn_mssql=新PDO(“sqlsrv:Server=$serverName;Database=”);
$conn_mssql->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_异常);
$conn_mysql=new PDO(“mysql:host=localhost;dbname=“,”,”);
$conn_mysql->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_异常);
//从SQL SERVER数据库中选择
$mssql_数组=数组();
$mssql_query=$conn_mssql->prepare(“从奖励中选择*);
$mssql_查询->执行();
while($row=$mssql\u query->fetch(PDO::fetch\u两者))
{
$mssql_数组[]=数组('id'=>$row['id']),
“IDNO”=>$row[“IDNO”],
'title'=>$row['title'],
'place'=>$row['place'],
“已授予”=>$row[“已授予”],
'datee'=>$row['datee']);
}
//清空MySQL表
$mysql\u query=$conn\u mysql->prepare(“截断表奖励”);
$mysql_query->execute();
if($mysql\u查询)
{
回显“截断成功”。
;
}
其他的
{
回声“截断错误”;
}
//将SQL Server DB中的值插入空MySQL表
$sql=$conn_mysql->prepare(“插入奖励值(:id,:IDNO,:title,:place,:designed,:datee)”);
foreach($mssql_数组作为$key=>$value)
{
$params_insert=数组(':id'=>$value['id'],
':IDNO'=>$value['IDNO'],
':title'=>$value['title'],
':place'=>$value['place'],
“:已授予”=>美元价值[“已授予”],
“:datee'=>$value['datee']);
$sql->execute($params_insert);
}
echo“来自MS SQL DB的表奖励和来自MySQL DB的表奖励现在已同步!”“
”;
回声“;
}
捕获(PDO$e)
{
回显“错误:”..e->getMessage();
}
?>
我从过去关于这个特殊问题的问题中寻找答案,但几乎所有问题都涉及固定值的变量。考虑到我正在使用一个数组来存储主表中的所有值,我不知道如何将其应用到我的代码中。我应该对代码进行哪些更改/添加以使其更快?如果您在60秒内完成800行,那么每秒只有13次插入,而且速度似乎非常慢,特别是对于包含预处理语句的代码。数据库真的很忙吗?那张表上有很多索引吗?您可以尝试基准测试与直接CSV插入(这通常是最快的),以了解性能瓶颈在哪里。这应该很快,至少每秒100次,如果不是更多的话,尤其是在一个有4GB内存和一个用于存储的中端SSD的服务器上。我不会用php在数据库之间传输这么多数据。这两台服务器可以明显地看到对方,因此我将mysql服务器作为链接服务器添加到ms sql server(您需要在ms sql server上安装myodbc)。然后直接传输数据。或者安装一个ETL工具,比如SSIS,并使用它来传输数据。或者将ms sql数据作为csv文件转储,然后使用load data Inflie将其加载到mysql中。@tadman我有一个单独的代码来比较两个表,并只插入差异。这一个几乎可以即时工作,但问题是出于某种原因,它只适用于一个表。我知道这两种方法的插入过程是不同的,但差别很大。这里真正的问题是,插入的每一行都会逐渐变慢,这表明存在某种索引性能问题,还是不管表有多大,插入的速度都会一直变慢?一个调优不好的MySQL服务器可能会有一些非常荒谬的默认值,比如在系统可能有更多内存的情况下,只给InnoDB 32MB(兆字节!)的内存。尽管这一点正在逐渐深入,但您可能想用一个工具来观察服务器的性能,比如查看您实际获得的性能。您还需要将从静态文件(例如CSV转储或JSON文件,任何易于使用的文件)到PHP进行比较,并消除等式中的SQL Server部分。还原过程!像这样,它能快速插入到其他MySQL服务器上吗?或者更新版本的MySQL?如果你在60秒内完成800行,那么每秒只有13次插入,而且速度似乎非常慢,特别是对于包含预处理语句的内容。数据库真的很忙吗?那张表上有很多索引吗?您可以尝试基准测试与直接CSV插入(这通常是最快的),以了解性能瓶颈在哪里。这应该很快,至少每秒100次,如果不是更多的话,尤其是在一个有4GB内存和一个用于存储的中端SSD的服务器上。我不会用php在数据库之间传输这么多数据。这两台服务器可以明显地看到对方,因此我将mysql服务器作为链接服务器添加到ms sql server(您需要在ms sql server上安装myodbc)。然后直接传输数据。或者安装一个ETL工具,比如SSIS,并使用它来传输数据。或者将ms sql数据作为csv文件转储,然后使用load data Inflie将其加载到mysql中。@tadman我有一个单独的代码来比较两个表,并只插入差异。这一个几乎完全可以在瞬间工作,但问题是出于某种原因