Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果值位于由另一个表组成的数组中,如何使用PHP和PDO在MySQL中更快地插入多行(~70k)?_Php_Mysql_Sql - Fatal编程技术网

如果值位于由另一个表组成的数组中,如何使用PHP和PDO在MySQL中更快地插入多行(~70k)?

如果值位于由另一个表组成的数组中,如何使用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

我试图将多行插入到一个被截断的表中,而这个过程需要很长时间才能完成。大约有800行,我需要60多秒才能完成,考虑到我必须对一个有70k行的表执行相同的过程,这已经是个问题了(我做了计算,大概需要1小时45分钟才能完成)。代码如下:


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我有一个单独的代码来比较两个表,并只插入差异。这一个几乎完全可以在瞬间工作,但问题是出于某种原因