2019-08-18 19:39:09 weixin_39442130 阅读数 25

PHP一次性向MySQL数据库插入大数量数据

实现功能

1,使用PHP实现往MySQL插入1000万条数据;

代码如下:

    public function dashuju()
    {
    	echo date('Y-m-d H:i:s', time());// 开始执行时间
    	set_time_limit(0);// 设置脚本执行时间
    	ini_set ('memory_limit', '102400M');// 设置进程占用内存

    	$sql= "insert into dashuju (size) values ";

    	for($i=0;$i<10000000;$i++){
    		$size = mt_rand(1,999999);
			$sql.="($size),";
		};

    	$sql = substr($sql,0,strlen($sql)-1);

    	Db::query($sql);// 执行sql语句
    	echo date('Y-m-d H:i:s', time());// 执行结束时间
    }
2018-01-22 16:42:00 LCRxxoo 阅读数 974

首先创建一个表(t3),只有一个字段



mysql有个功能是存储:



\d // :命令作用是改变语句定界符(本来是 分号 ; 现在改变成双斜杠 //)


最后使用 call p3() 执行存储


2019-06-18 14:38:21 codipy 阅读数 511

有3种方法实现插入数据

  1. insert, 返回值是影响记录的行数,插入数
  2. insertGetId 返回插入数据的自增加id
  3. insertAll() 一次性插入多条数据, 返回数据成功的行数
<?php

namespace app\index\controller;

use think\Controller;
use think\Db;

class Index extends Controller
{
    public function index()
    {
        $db = Db::name('user');

        # 1.insert 返回值是影响记录的行数  插入数
        /*
        $res = $db->insert([
            'email'    => 'imooc_02',
            'password' => md5('imooc_02'),
            'username' => 'imooc_02',
        ]);
        */

        # 2. insertGetId 获取新增项目的id
        # 返回插入数据的自增id
        /*
        $res = $db->insertGetId([
            'email'    => 'imooc_03',
            'password' => md5('imooc_03'),
            'username' => 'imooc_03',
        ]);
        */

        # 3. insertAll() 一次性插入多条数据
        # 返回插入数据成功的行数
        $data = [];
        for ($i = 10; $i < 20; $i++) {
            $data[] = [
                'email'    => "imooc_03_{$i}@qq.com",
                'password' => md5("imooc_03_{$i}"),
                'username' => "imooc_03_{$i}",
            ];
        }
        $res = $db->insertAll($data);
        dump($res);

    }


}

 

2014-04-01 16:07:27 svap1 阅读数 1381

       之前遇到个问题,需要将一个文件夹中的所有文件名取出并 存入到数据库中。

       采用php脚本测试,读取一个文件名,就立即存储到数据库中,结果花了我230多秒的时间,速度实在太慢!

      

       原因分析:insert 语句被执行了6000次,导致速度特别慢!

       改进方法:1、用php脚本 将 所有的文件名都存入到一个文本文件中filename.txt(一个文件名占一行),实测脚本执行时间 1.5262秒。

                           2、用php的fgets()函数取出filename.txt中的每一行数据,保存到buffer数组中,将buffer数组写入到一条insert语句中,

                             执行一次insert语句,实测脚本执行时间 0.0629秒。

       代码1的功能是提取目录test下的文件名,并将其保存到“filename.txt”中如下:

<?php
$st=microtime_float();//自定义函数,在代码2中可见。
       $cout=0;$dir="e:/pydot";$talbe="pydot2";
              if(is_dir($dir)){ 
                     if($dh=opendir($dir)) { 
                            while(($file=readdir($dh)) !== false){ 
                                   if($file!="."&&$file!=".."){ 
                                   $file=mb_convert_encoding($file,'UTF-8','EUC-CN');
                                   $filename="test/filename.txt";
                                   if(!$handle = fopen($filename, 'a')) {
                                    echo "不能打开文件$filename";
                                    exit;
                                   }
                            //将$file写入到我们打开的文件中。
                                   fputs($handle,$file."\n");
                                   $cout++;
                                   echo $file."<br>";
                                   } 
                            } 
                     closedir($dh); 
                     } 
              } 
       $et=microtime_float();
       $t=$et-$st;
       echo"insert into talbe ",$talbe,"",$cout,"times;\n<br>";
       echo"Total time $t seconds.\n";
?>


              代码2的功能是将“filename.txt”中的文件名存入到数据库中,如下:

<?php     
       $server='localhost';
       $user='root';
       $passwd='root';
       $port='3306';
       $dbname='dbname';
       $talbe="tablename";
       $c=0;$cc=0;
       $st=microtime_float();
       $link=mysql_connect($server,$user,$passwd);
       if(!$link) {
              die('Couldnot connect: ' . mysql_error());
       }
       else echo 'Connected successfully\n<br>'; 
       mysql_select_db("catx",$link);
       $handle= @fopen("sq.txt", "r");
       //读取sq.txt中的内容,执行插入操作
       while((fgets($handle, 256)) !== false) {
              $buffer[$c]= fgets($handle, 256);
              $c++;
              if(0==$c%5978){
                     $c=0;$start_c="('";$end_c="');"; //
                     $va="";
                     $kh="'),('";//括号
                         for($i=0;$i<5978;$i++){
                         $va.=$buffer[$i].$kh;  //拼接sql语句
                          }
                     $sql="insertinto tablename(name) values".$start_c.$va.$end_c;
                     mysql_query($sql);
              }
              $cc++;
       }      
       $et=microtime_float();
       $t=$et-$st;
       echo"Totaltime $t seconds.\n<br>";
       echo"insert into talbe ",$talbe,"",$cc,"times;\n<br>";
       
       functionmicrotime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
?>

      

 


2017-12-20 09:55:00 luogan129 阅读数 5293

当有业务需求需要一次性循环n条数据,插入或更新数据库时,如果单纯的循环,插入/更新,会消耗太多的数据库资源


一下是一种简单的解决方案


数据库的insert 是可以批量更新的,当有大量数据循环insert时,可以将数据先保留不执行插入命令,到最后一条时一次性插入,例如tp的addAll()方法;


数据库的update 如果使用case when 的话,也是可以批量更新的,本人在百度上找到了一个基于tp的saveAll()方法,用于更新数据

本文主要讲关于批量insert;

例:


生成一个订单


正常情况的语句为:

INSERT INTO order (`goods_id`,`num`,`price`) VALUES (1,1,'10.00');
//封装成函数
function add_order($goods_id,$num,$price){
$db->query("INSERT INTO order (`goods_id`,`num`,`price`) VALUES ($goods_id,$num,$price)");
}

假设有一个用户,一次性将购物车的1000个商品结算成订单,生成1000个订单时;

for ($i=0;$i<1000;$i++){
$db->query("INSERT INTO order (`goods_id`,`num`,`price`) VALUES ($goods_id,$num,$price)");
}
//这样的话会导致服务器资源占用过大,网站卡死
//所以,我们可以
$sql "INSERT INTO order (`goods_id`,`num`,`price`) VALUES ";
for ($i=0;$i<1000;$i++){
    if($i==0){
    $sql.="($goods_id,$num,$price)";
    }else{
    $sql.=",($goods_id,$num,$price)";
    }
}
$db->query($sql);

大概意思就是这样了,批量更新实现比较麻烦一点,就不发了,以下是批量更新的sql执行语句

UPDATE tiyan.dm_user_cupboard SET `res_id` = CASE `id` WHEN 1041 THEN '1' WHEN 1058 THEN '1' WHEN 1055 THEN '1'  END,`food_code` = CASE `id` WHEN 1041 THEN '68' WHEN 1058 THEN '47' WHEN 1055 THEN '49'  END,`food_name` = CASE `id` WHEN 1041 THEN '红枣' WHEN 1058 THEN '莲藕' WHEN 1055 THEN '洋葱'  END,`num` = CASE `id` WHEN 1041 THEN '2' WHEN 1058 THEN '3' WHEN 1055 THEN '2'  END,`level` = CASE `id` WHEN 1041 THEN '2' WHEN 1058 THEN '2' WHEN 1055 THEN '2'  END,`update_time` = CASE `id` WHEN 1041 THEN '2017-12-09 21:40:06' WHEN 1058 THEN '2017-12-09 21:40:06' WHEN 1055 THEN '2017-12-09 21:40:06'  END WHERE id IN ( 1041,1058,1055 )

UPDATE tiyan.dm_user_cupboard SET `res_id` = CASE `id` WHEN 1041 THEN '1' WHEN 1058 THEN '1' WHEN 1055 THEN '1'  END,`food_code` = CASE `id` WHEN 1041 THEN '68' WHEN 1058 THEN '47' WHEN 1055 THEN '49'  END,`food_name` = CASE `id` WHEN 1041 THEN '红枣' WHEN 1058 THEN '莲藕' WHEN 1055 THEN '洋葱'  END,`num` = CASE `id` WHEN 1041 THEN '2' WHEN 1058 THEN '3' WHEN 1055 THEN '2'  END,`level` = CASE `id` WHEN 1041 THEN '2' WHEN 1058 THEN '2' WHEN 1055 THEN '2'  END,`update_time` = CASE `id` WHEN 1041 THEN '2017-12-09 21:40:06' WHEN 1058 THEN '2017-12-09 21:40:06' WHEN 1055 THEN '2017-12-09 21:40:06'  END WHERE id IN ( 1041,1058,1055 )




附带基于tp的saveAll()


//批量更新
public function saveAll($datas,$model){
    $model || $model=$this->tableName);
    $model=empty($model)?$this->name:$model;
    $sql   ''//Sql
    $lists = []; //记录集$lists
    $pk    $this->getPk();//获取主键
    foreach ($datas as $data) {
        foreach ($data as $key=>$value) {
            if($pk===$key){
                $ids[]=$value;
            }else{
                $lists[$key].= sprintf("WHEN %u THEN '%s' ",$data[$pk],$value);
            }
        }
    }
    foreach ($lists as $key => $value) {
        $sql.= sprintf("`%s` = CASE `%s` %s END,",$key,$pk,$value);
    }
    $sql = sprintf('UPDATE __%s__ SET %s WHERE %s IN ( %s )',strtoupper($model),rtrim($sql,','),$pk,implode(',',$ids));
    return M()->execute($sql);
}


----


pdo批量插入数据

阅读数 2436

没有更多推荐了,返回首页