php执行语句在MySQL批量插入大数据量的解决方案及计算程序执行时间(大数据量、MySQL语句优化)

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: php执行语句在MySQL批量插入大数据量的解决方案及计算程序执行时间(大数据量、MySQL语句优化)

前言

近期在MySQL报表开发过程中,需要爬取多API返回JSON数据,然后插入到数据库中。因不同API的返回时间、返回数据、返回格式、插入数据表等因素各不相同。如果前期架构不完善,会导致服务器的直接崩溃,为此,做了下php+mysql的批量插入大数据量的测试工作。


一、PHP计算程序执行时间

microtime() 函数,返回当前 Unix 时间戳的微秒数,都是以秒为单位返回。

执行代码:

$start_time = microtime();
/*
 * 执行程序代码;
 * */
$end_time = microtime();
echo '执行时间为:' . ($end_time - $start_time)  . ' s';


原理:分别记录函数开始时间和结束时间,然后时间差就是函数执行的时间。

二、Mysql批量插入数据

1.INSERT INTO 语句

  • 向表格中插入新的行
INSERT INTO 表名称 VALUES (值1, 值2,....)
  • 指定所要插入数据的列
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)

2.批量插入大数据

  • Mysql插入少量数据的时候,一般用for循环:读取固定结构化的数据或JSON数据,通过遍历的方式插入;

上图是一次性插入3000条的测试数据。

2.1 使用循环$sql的方式


  • MySQL使用insert语句进行合并插入的,比如INSERT INTO user_info (name, age) VALUES (‘name1’, 18), (‘name2’, 19);表示一次插入两条数据。

执行代码:

$sql = ' INSERT INTO ' . $db->table('log') . ' (user_name,logs,equipment,log_time,log_ip) VALUES ("' . $data[$i][0] . '","' . $data[$i][1] . '","' . $data[$i][2] . '","' . $data[$i][3] . '","' . $data[$i][4] . '")';
$db->query($sql);


$sql = ' INSERT INTO ' . $db->table('log') . ' VALUES ("' . ($i + 1) . '","' . $data[$i][0] . '","' . $data[$i][1] . '","' . $data[$i][2] . '","' . $data[$i][3] . '","' . $data[$i][4] . '")';
 $db->query($sql);


执行结果:不仅未完成数据的全部插入,直接将服务器拖成了500 Internal Server Error 。

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at admin@example.com to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.

Additionally, a 500 Internal Server Error error was encountered while trying to use an ErrorDocument to handle the request.



2.2 循环(值1, 值2,…)的语句

  • 执行效率奇高;
  • 对服务器的压力可以忽略不计;
  • 批量插入大数据量MySQL的优化,推荐本方案;
  • 大数据量插入mysql的语句(执行时间)★★★


 //批量添加数据;
    public function addData()
    {
        global $db;
        dbc();
        $start_time = microtime();//开始时间
        require_once 'data.php';//默认数据
        $sql = 'INSERT INTO ' . $db->table('log') . ' (user_name,logs,equipment,log_time,log_ip) VALUES ';
        for ($i = 0; $i < count($data); $i++) {
            $itemStr = '("';
            $itemStr .= $data[$i][0] . '","' . $data[$i][1] . '","' . $data[$i][2] . '","' . $data[$i][3] . '","' . $data[$i][4];
            $itemStr .= '"),';
            //echo $itemStr;
            $sql .= $itemStr;
        }
        $sql = rtrim($sql, ',');//去除最后一个逗号,并且加上结束分号
        $sql .= ';';
        $db->query($sql);
        $end_time = microtime();//结束时间
        $res["time"] = '执行时间:' . ($end_time - $start_time) . 's';
        $res["data"] = "数据录入完毕.";
        die(json_encode_lockdata($res));
    }
  • 实际开发取消时间验证★★★
 //批量添加数据;
    public function addData()
    {
        global $db;
        dbc();
        require_once 'data.php';//默认数据
        $sql = 'INSERT INTO ' . $db->table('log') . ' (user_name,logs,equipment,log_time,log_ip) VALUES ';
        for ($i = 0; $i < count($data); $i++) {
            $itemStr = '("';
            $itemStr .= $data[$i][0] . '","' . $data[$i][1] . '","' . $data[$i][2] . '","' . $data[$i][3] . '","' . $data[$i][4];
            $itemStr .= '"),';
            //echo $itemStr;
            $sql .= $itemStr;
        }
        $sql = rtrim($sql, ',');//去除最后一个逗号,并且加上结束分号
        $sql .= ';';
        $db->query($sql);
        $res["data"] = "数据录入完毕.";
        die(json_encode_lockdata($res));
    }


  • 拼接语句
 for ($i = 0; $i < count($data); $i++) {
            $itemStr = '(';
            $itemStr .= $data[$i][0] . ',' . $data[$i][1] . ',' . $data[$i][2] . ',' . $data[$i][3] . ',' . $data[$i][4];
            $itemStr .= '),';
            //echo $itemStr;
            $sql .= $itemStr;
        }


2.3测试过程出现的错误

“Unknown column ‘xxx’ in 'where clause


主要意思就是这个字段不存在,但实际情况有可能插入字段符合规范导致的。比如:username字段是varchar类型,而变量解析之后由于不带单引号,在PHP里面虽然可以当成字符串用,但执行sql语句就不符合Mysql的规范了。

错误的写法1:

 $sql = ' INSERT INTO ' . $db->table('log') . ' (user_name,logs,equipment,log_time,log_ip) VALUES (' . $data[$i][0] . ',' . $data[$i][1] . ',' . $data[$i][2] . ',' . $data[$i][3] . ',' . $data[$i][4] . ')';
$db->query($sql);


错误的写法2:

 $sql = ' INSERT INTO ' . $db->table('log') . ' (user_name,logs,equipment,log_time,log_ip) VALUES ($data[$i][0],$data[$i][1],$data[$i][2],$data[$i][3],$data[$i][4])';
$db->query($sql);


SQL语句错误号:Column count doesn’t match value count at row 1


SQL语句错误号:You have an error in your SQL syntax; check the manual that

corresponds to your MySQL server version for the right syntax to use

near ‘.162.76),(NO.0000007,10,LOCKDATAV机器人模拟数据-SHELL,1681302901,无法’ at

line 1


上面的错误,基本上都是因文本没有加引号导致的。


三、实战PHPExcel批量导入大数据量优化

循环读取excel表格,读取一条,插入一条,需要每次都连接数据库,执行效率比较低下。

 //循环读取excel表格,读取一条,插入一条
        //j表示从哪一行开始读取  从第二行开始读取,因为第一行是标题不保存
        //$a表示列号
        for ($j = 2; $j <= $highestRow; $j++) {
            $user_province = $objPHPExcel->getActiveSheet()->getCell("A" . $j)->getValue();
            $user_city = $objPHPExcel->getActiveSheet()->getCell("B" . $j)->getValue();
            $user_area = $objPHPExcel->getActiveSheet()->getCell("C" . $j)->getValue();
            $user_depart = $objPHPExcel->getActiveSheet()->getCell("D" . $j)->getValue();
            $user_titles = $objPHPExcel->getActiveSheet()->getCell("E" . $j)->getValue();
            $user_name = $objPHPExcel->getActiveSheet()->getCell("F" . $j)->getValue();
            $user_phone = $objPHPExcel->getActiveSheet()->getCell("G" . $j)->getValue();
            $user_pwd = $objPHPExcel->getActiveSheet()->getCell("H" . $j)->getValue();
            $user_auth = $objPHPExcel->getActiveSheet()->getCell("I" . $j)->getValue();
            //判断手机号重名;
            $row = $db->fetch('user', 'user_phone', array('user_phone' => trim($user_phone)), ' user_id DESC');
            if ($row) {
                $res['code'] = '0';
                $res['msg'] = $user_phone . '系统已存在,删除后重新导入';
                die(json_encode_lockdata($res));
            }
            //数据入库;
            if ($user_phone) {
 $db->insert('user', array('user_province' => $user_province, 'user_city' => $user_city, 'user_area' => $user_area, 'user_depart' => $user_depart, 'user_titles' => $user_titles,'user_name' => $user_name, 'user_phone' => $user_phone, 'user_pwd' => md5($user_pwd), 'user_auth' => $user_auth));
            }
        }
        $res['code'] = '1';
        $res['msg'] = '文件已导入数据库!';
        die(json_encode_lockdata($res));


升级后的代码:

 global $db;
        dbc();
        $sql = 'INSERT INTO ' . $db->table('user') . ' (user_province,user_city,user_area,user_depart,user_titles,user_name,user_phone,user_pwd,user_auth) VALUES ';
        for ($j = 2; $j <= $highestRow; $j++) {
            $user_province = $objPHPExcel->getActiveSheet()->getCell("A" . $j)->getValue();
            $user_city = $objPHPExcel->getActiveSheet()->getCell("B" . $j)->getValue();
            $user_area = $objPHPExcel->getActiveSheet()->getCell("C" . $j)->getValue();
            $user_depart = $objPHPExcel->getActiveSheet()->getCell("D" . $j)->getValue();
            $user_titles = $objPHPExcel->getActiveSheet()->getCell("E" . $j)->getValue();
            $user_name = $objPHPExcel->getActiveSheet()->getCell("F" . $j)->getValue();
            $user_phone = $objPHPExcel->getActiveSheet()->getCell("G" . $j)->getValue();
            $user_pwd = $objPHPExcel->getActiveSheet()->getCell("H" . $j)->getValue();
            $user_auth = $objPHPExcel->getActiveSheet()->getCell("I" . $j)->getValue();
            //判断手机号重名;
            $row = $db->fetch('user', 'user_phone', array('user_phone' => trim($user_phone)), ' user_id DESC');
            if ($row) {
                $res['code'] = '0';
                $res['msg'] = $user_phone . '系统已存在,删除后重新导入';
                die(json_encode_lockdata($res));
            }
            //数据入库;
            $itemStr = '("';
            $itemStr .= $user_province . '","' . $user_city . '","' . $user_area . '","' . $user_depart . '","' . $user_titles . '","' . $user_name . '","' . $user_phone . '","' . md5($user_pwd) . '","' . $user_auth;
            $itemStr .= '"),';
            $sql .= $itemStr;
        }
        $sql = rtrim($sql, ',') . ";";
        $db->query($sql);
        $res['code'] = '1';
        $res['msg'] = '文件已导入数据库!';
        die(json_encode_lockdata($res));
    }

如在上传过程过程中出现错误,请务必核对插入列数是否前后一致即可。

@漏刻有时


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
5月前
|
存储 SQL 分布式计算
大数据之路:阿里巴巴大数据实践——元数据与计算管理
本内容系统讲解了大数据体系中的元数据管理与计算优化。元数据部分涵盖技术、业务与管理元数据的分类及平台工具,并介绍血缘捕获、智能推荐与冷热分级等技术创新。元数据应用于数据标签、门户管理与建模分析。计算管理方面,深入探讨资源调度失衡、数据倾斜、小文件及长尾任务等问题,提出HBO与CBO优化策略及任务治理方案,全面提升资源利用率与任务执行效率。
|
4月前
|
关系型数据库 MySQL PHP
PHP和Mysql前后端交互效果实现
本文介绍了使用PHP连接MySQL数据库的基本函数及其实现案例。内容涵盖数据库连接、选择数据库、执行查询、获取结果等常用操作,并通过用户登录和修改密码的功能实例,展示了PHP与MySQL的交互过程及代码实现。
361 0
PHP和Mysql前后端交互效果实现
|
9月前
|
关系型数据库 MySQL Linux
查看Linux、Apache、MySQL、PHP版本的技巧
以上就是查看Linux、Apache、MySQL、PHP版本信息的方法。希望这些信息能帮助你更好地理解和使用你的LAMP技术栈。
473 17
|
10月前
|
关系型数据库 MySQL PHP
源码编译安装LAMP(HTTP服务,MYSQL ,PHP,以及bbs论坛)
通过以上步骤,你可以成功地在一台Linux服务器上从源码编译并安装LAMP环境,并配置一个BBS论坛(Discuz!)。这些步骤涵盖了从安装依赖、下载源代码、配置编译到安装完成的所有细节。每个命令的解释确保了过程的透明度,使即使是非专业人士也能够理解整个流程。
313 18
|
11月前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
442 25
|
SQL 关系型数据库 MySQL
PHP与MySQL的高效交互:从基础到实践####
本文深入探讨了PHP与MySQL数据库之间的高效交互技术,涵盖了从基础连接到高级查询优化的全过程。不同于传统的摘要概述,这里我们直接以一段精简代码示例作为引子,展示如何在PHP中实现与MySQL的快速连接与简单查询,随后文章将围绕这一核心,逐步展开详细讲解,旨在为读者提供一个从入门到精通的实战指南。 ```php <?php // 数据库配置信息 $servername = "localhost"; $username = "root"; $password = "password"; $dbname = "test_db"; // 创建连接 $conn = new mysqli($se
354 31
|
SQL 分布式计算 DataWorks
MaxCompute MaxFrame评测 | 分布式Python计算服务MaxFrame(完整操作版)
在当今数字化迅猛发展的时代,数据信息的保存与分析对企业决策至关重要。MaxCompute MaxFrame是阿里云自研的分布式计算框架,支持Python编程接口、兼容Pandas接口并自动进行分布式计算。通过MaxCompute的海量计算资源,企业可以进行大规模数据处理、可视化数据分析及科学计算等任务。本文将详细介绍如何开通MaxCompute和DataWorks服务,并使用MaxFrame进行数据操作。包括创建项目、绑定数据源、编写PyODPS 3节点代码以及执行SQL查询等内容。最后,针对使用过程中遇到的问题提出反馈建议,帮助用户更好地理解和使用MaxFrame。
|
4月前
|
机器学习/深度学习 传感器 分布式计算
数据才是真救命的:聊聊如何用大数据提升灾难预警的精准度
数据才是真救命的:聊聊如何用大数据提升灾难预警的精准度
359 14
|
6月前
|
数据采集 分布式计算 DataWorks
ODPS在某公共数据项目上的实践
本项目基于公共数据定义及ODPS与DataWorks技术,构建一体化智能化数据平台,涵盖数据目录、归集、治理、共享与开放六大目标。通过十大子系统实现全流程管理,强化数据安全与流通,提升业务效率与决策能力,助力数字化改革。
234 4
|
5月前
|
机器学习/深度学习 运维 监控
运维不怕事多,就怕没数据——用大数据喂饱你的运维策略
运维不怕事多,就怕没数据——用大数据喂饱你的运维策略
217 0

推荐镜像

更多