将数组数据插入mysql表的高效php代码?

Posted

技术标签:

【中文标题】将数组数据插入mysql表的高效php代码?【英文标题】:Efficient php code to insert array data into mysql table? 【发布时间】:2012-10-01 07:44:12 【问题描述】:

所以我有一个格式为的平面文件数据库 用户名:$SHA$1010101010101010$010110010101010010101010100101010101001010:255.255.255.255:1342078265214

新行上的每条记录......大约 5000 多行......我想将它导入到 mysql 表中。通常我会使用 phpmyadmin 和“文件导入”来执行此操作,但现在我想通过使用 php 通过 ftp 下载数据库然后清理现有表数据并上传更新的数据库来自动化此过程。

id(AUTH INCREMENT) | username | password | ip | lastlogin

我在下面得到的脚本大部分都可以工作.. 虽然 php 会产生一个错误: “PHP致命错误:超过30秒的最大执行时间”我相信我可以增加这个时间,但在远程服务器上我怀疑我会被允许,所以我需要找到更好的方法。

在超时之前只有大约 1000 条记录会被插入到数据库中......

我正在使用的代码如下.. 我会说现在我不是 php 的专业人士,这主要是收集和拼凑在一起的。我正在寻求一些帮助以提高效率,因为我听说做这样的插入很糟糕。听起来真的很糟糕,因为当我在本地电脑上运行这个脚本时会刮很多磁盘。我的意思是为什么它要杀死硬盘来完成这样一个看似简单的任务。

<?php
require ('Connections/local.php');

$wx = array_map('trim',file("auths.db"));
$username = array();
$password = array();
$ip = array();
$lastlogin = array();
foreach($wx as $i => $line) 

        $tmp = array_filter(explode(':',$line));
        $username[$i] = $tmp[0];
        $password[$i] = $tmp[1];
        $ip[$i] = $tmp[2];
        $lastlogin[$i] = $tmp[3];

mysql_query("INSERT INTO authdb (username,password,ip,lastlogin) VALUES('$username[$i]', '$password[$i]', '$ip[$i]', '$lastlogin[$i]') ") or die(mysql_error()); 

?>

【问题讨论】:

在一个查询中插入多行应该会显着提高性能。 由于您使用 mysql_query 而不使用 proper SQL escaping,为了您自己的安全,您可能应该使用 mysqli 或 PDO。 我建议切换到使用fgets,而不是将整个文件拆分为一个数组,这也会提高速度。 我会考虑使用 fgets,尽管我认为我目前真正遇到的问题是以 php 不会提前超时的方式将其放入 mysql db。 @alfasin - 我假设你的母语不是英语。 aswel --> as well,(或“also”,或“additionally”)——这是一个拼写错误。 :) 【参考方案1】:

试试这个,绑定参数和 PDO。

<?php
require ('Connections/local.php');

$wx = array_map('trim',file("auths.db"));
$username = array();
$password = array();
$ip = array();
$lastlogin = array();

try 
    $dbh = new PDO("mysql:host=$ip;dbname=$database", $dbUsername, $dbPassword);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
 catch(PDOException $e) 
    echo 'ERROR: ' . $e->getMessage();


$mysql_query = "INSERT INTO authdb (username,password,ip,lastlogin) VALUES(:username, :password, :ip, :lastlogin)";
$statement = $dbh->prepare($mysql_query);

foreach($wx as $i => $line) 
        set_time_limit(0);

        $tmp = array_filter(explode(':',$line));
        $username[$i] = $tmp[0];
        $password[$i] = $tmp[1];
        $ip[$i] = $tmp[2];
        $lastlogin[$i] = $tmp[3];

        $params = array(":username"  => $username[$i],
                        ":password"  => $password[$i],
                        ":ip"        => $ip[$i],
                        ":lastlogin" => $lastlogin[$i]);
        $statement->execute($params);

?>

【讨论】:

感谢分享。虽然我得到了一些坏消息,但我立即对其进行了测试。 PHP 仍然在 30 秒时超时。 //1,188 条记录被插入...我测试了我拥有的原始脚本并管理了 //1,085 条插入的记录。有没有办法绕过这个 php 限制?除了增加限制? php.ini 中max_execution_time 的值是多少?你是从命令行运行的吗? 我只是从 h**p://localhost 运行 php 脚本......另外 php.ini 是 max_execution_time = 30 。这对于“PHP致命错误:最大执行超过 30 秒的时间”我得到的错误。就像我说的我可以在这里更改它,但我认为我不会被允许在远程服务器上,理想情况下我希望拥有这个脚本,以便更快地更新数据库。 尝试在你的 foreach 循环中添加set_time_limit(0) 我很高兴。这应该在远程服务器上工作,除非 PHP 在其上以安全模式运行。如果它对您的 mysql 有帮助,请随时接受我提供的答案。这种绑定参数样式不仅高效,而且相当安全。【参考方案2】:

而不是以表单的形式一一向服务器发送查询

insert into table (x,y,z) values (1,2,3)

您应该使用扩展插入语法,如:

insert into table (x,y,z) values (1,2,3),(4,5,6),(7,8,9),...

这将使插入性能提高英里。但是,您需要注意在一条语句中插入多少行,因为单个 SQL 的大小是有限制的。所以,我会说从 100 排包装开始,看看情况如何,然后相应地调整包装尺寸。您的插入时间很可能会下降到 5 秒,低于 max_execution_time 限制。

【讨论】:

以上是关于将数组数据插入mysql表的高效php代码?的主要内容,如果未能解决你的问题,请参考以下文章

通过 PHP 将数据插入 MySQL 表时出错

PHP:将数组数据插入 MySQL 数据库

PHP PHP:使用数组将数据插入MySQL表[mysql] [php] [array] [INSERT]

将php数组插入mySql

如何将php数组插入mysql表

PHP:使用数组[MySQL][PHP][Array][Insert]将数据插入MySQL表