首页 > 编程技术 > php

php导入大量数据到mysql性能优化

发布时间:2016-11-25 16:35

在mysql中我们结合php把一些文件导入到mysql中,下面我来分享我对15000条记录进行导入时分析与优化,各位朋友可参考。


之前有几篇文章,说了最近tiandi在帮朋友做一个小项目,用于统计电话号码的,每次按需求从数据库里随机生成打包的电话号码,然后不停地让人打这些电话号码推销产品(小小鄙视一下这样的行为)。但是朋友要求帮忙,咱也不能不帮啊,是吧。程序两个星期前已经做好,测试完毕交工。前几天朋友来电说,每天导入电话号码的时间越来越长,有时候一万条记录就要半个小时以上,看看能不能想办法提高一下这个速度。

我理了一下思路,数据库结构很简单,可以认为就两个字段,一个字段存电话号码,另一字段存类别,类别分别为c,d,e等等,分别代表已经拨通过此电话,未拨通过此电话,未拨打过此电话等等状态,而整个程序逻辑是这样的:

■拿到一个txt文件,里面存的是电话号码
■通过程序将txt文件导入到mysql里
■导入的时候,检测txt里的电话号码是否和mysql里的重复,如果不重复,直接插入新记录,如果重复,就需要按照判断电话号码所属类别来进行更新。
由于每个txt里的电话号码导入时,都需要做一次比较,所以程序肯定会耗时一些,这里我们先撇开这个原因,因为本文章的标题是优化写入速度,那么程序什么时候会写入记录呢?通过上面的逻辑得知,在匹配数据库时,没有发现存在记录时会发生写入数据库操作(当然update也算,只是这里只讨论insert)。那么将上述逻辑转化为代码,差不多如下:

 代码如下 复制代码

//$array为txt文件explode出来的数组,每一个为一个电话号码, $str为类型
for($i=0; $i<count($array); $i++)
    {
        $tmpstr = "'". $array[$i] ."','". $str ."'";
        $sql="INSERT INTO ".$usertable." (tel,type) VALUES (".$tmpstr.")";
        mysql_query($sql);
    }

以上代码完全正确,但是效率低下,当txt文件里包含了上万个电话号码时,即会有上万次的插入数据库操作,虽然每次的数据库写入操作都是很快的,但是上万条累计下来,这个执行时间不容忽视。tiandi简单的测试了一下插入15000万条记录,耗时差不多5分钟。如果再加上之前的逻辑判断等等过程,那么半个小时还真得不算少了。这样可不行,必须减少数据库库写入次数才对,于是上面代码变更为以下:

 代码如下 复制代码

$sql2="INSERT INTO ".$usertable." (tel,type,updatetime) VALUES";
for($i=0; $i<count($array); $i++)
    {
        $tmpstr = "'". $array[$i] ."','". $str ."'";
 $sql2 .= "(".$tmpstr."),";
    }
$sql2 = substr($sql2,0,-1);   //去除最后的逗号
mysql_query($sql2);

这样,整个写入操作只有1次,大大地缩短了执行时间,差不多10秒就搞定了15000条记录。好了,本文到此结束,如果你也遇上写入大量数据到mysql耗时长的问题时,不如试试本文的优化方式。

最近需要把一个以前的asp网站转换成php的,但php是与mysql而我的asp与mssql的,结果就需要把mssql数据导入到mysql数据库了,下面我自己写了一个实例还抄了一个实例都不错。

实例一

 代码如下 复制代码

<?php
//国内的PNR码连接
$hostname="127.0.0.1"; //MSSQL服务器的IP地址 或 服务器的名字
$dbuser="sa"; //MSSQL服务器的帐号
$dbpasswd="sa"; //MSSQL服务器的密码
$dbname="aa"; //数据库的名字

$conn = mssql_connect($hostname,$dbuser,$dbpasswd); //连接MSSQL
mssql_select_db($dbname); /*连接要访问的数据库 这里也可以写做 $db=mssql_select_db($dbname,$conn); */
$sql =
"select * from Sheet1$"; //sql语句
$data = mssql_query($sql); //把查询的值集合在变量$data
while($Arr = mssql_fetch_object($data)) //循环初始的集合$Arr

{
$Airport=$Arr->Airport;
$citycode=$Arr->citycode;
$Chinesecityname=$Arr->Chinesecityname;
$Chinesecityjp=$Arr->Chinesecityjp;
$english=$Arr->english;
$countrycode=$Arr->countrycode;
$countryfullname=$Arr->countryfullname;
$Chauname=$Arr->Chauname;
//echo $code;
$conn=mysql_connect("localhost","root","123456");//连接数据库的帐号和端口号
mysql_query("SET NAMES ‘GBK’",$conn);
mysql_select_db("taojipiao2009",$conn);// 加载数据库
//$sql="update internationcode set jp=’$aa’ where Code=’$Code’";
$sql="insert into internationcode(Airport,citycode,Chinesecityname,Chinesecityjp,english,countrycode,countryfullname,Chauname) values(‘$Airport‘,’$citycode‘,’$Chinesecityname‘,’$Chinesecityjp‘,’$english‘,’$countrycode‘,’$countryfullname‘,’$Chauname‘)";
//echo $sql."<br>";
$result=mysql_query($sql);
}
//mssql_close($conn); //关闭数据库

?>

 

 

参考代码二、

 代码如下 复制代码

<?php

$mssql_link = mssql_connect($db_host,$db_msuser,$db_mspass) or
die("mssql数据库连接失败");

mssql_select_db($db_msname,$mssql_link);

$mysql_link = mysql_connect($db_myhost,$db_myuser,$db_mypass) or die("mysql数据库连接失败".mysql_error());

mysql_select_db($db_myname,$mysql_link);

$msquery = mssql_query("select top 1 * from buyok_produc",$mssql_link);

$vars = ”;
$vals = ”;
$cols = ”;

while ($row = mssql_fetch_array($msquery,$mssql_link)){
    $vals = ”;
    foreach($row as $key=>$values){
        $cols .= ($cols == ” ? $key : ‘,‘.$key);
        $vals .= ($vals == ” ? ‘’‘.$values.‘’,‘ : ‘’‘.$values.‘’,‘);
        //echo $vals;
    }
    $vars .= ($vars == ” ? ‘(‘.$vals.‘)‘ : ‘,(‘.$vals.‘)‘);
}

$sql =
"insert into `buyok_produc` ($cols) values $vars";

echo $sql;

$aa=mysql_query($sql, $mysql_link);

if ($aa){
    echo "successfully";
}else{
    echo "failed";
}

?>

本文章来给大家介绍PHP利用curl实现get与POST提交数据方法,各位朋友有需要了解的可进入参考。


curl实现get提交数据

 代码如下 复制代码
// 初始化一个 cURL 对象
$curl = curl_init();
// 设置你需要抓取的URL
curl_setopt($curl, CURLOPT_URL, 'http://www.111cn.net');
// 设置header, 最后一个参数是0表示返回值不带有header,1表示带有header
curl_setopt($curl, CURLOPT_HEADER, 0);
// 设置浏览器的特定header,可选,如果目标网站有要求的话
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"User-Agent: {'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)'}",
"Accept-Language: {en-us,en;q=0.5}"
));
//或者只设置user-agent,可选,如果目标网站有要求的话
curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1");
// 设置cURL 参数,要求结果保存到字符串中还是输出到屏幕上,1表示保存到字符串
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// 页面内容不需要时,设置为1. 默认为0
curl_setopt($ch, CURLOPT_NOBODY, 1);
// 运行cURL,请求网页,保存在$data
$data = curl_exec($curl);
// 关闭URL请求
curl_close($curl);
//检查错误
//比较的时候我们用的是“=== FALSE”,而非“== FALSE”,因为我们得区分’空输出‘和’布尔值FALSE‘
if ($output === FALSE) {
echo "cURL Error: " . curl_error($ch);
}
//可以获取信息
$info = curl_getinfo($ch);
echo '获取'. $info['url'] . '耗时'. $info['total_time'] . '秒';
/* ...返回的数组中包括了以下信息:
“url” //资源网络地址
“content_type” //内容编码
“http_code” //HTTP状态码
“header_size” //header的大小
“request_size” //请求的大小
“filetime” //文件创建时间
“ssl_verify_result” //SSL验证结果
“redirect_count” //跳转技术
“total_time” //总耗时
“namelookup_time” //DNS查询耗时
“connect_time” //等待连接耗时
“PRetransfer_time” //传输前准备耗时
“size_upload” //上传数据的大小
“size_download” //下载数据的大小
“speed_download” //下载速度
“speed_upload” //上传速度
“download_content_length”//下载内容的长度
“upload_content_length” //上传内容的长度
“starttransfer_time” //开始传输的时间
“redirect_time”//重定向耗时
*/

curl实现POST提交数据

http的post实现

 代码如下 复制代码

//extract data from the post
extract($_POST) ; 
//set POST variables
$url = 'http://www.111cn.net' ;
$fields = array(
            'lname'=&gt;urlencode($last_name) ,
            'fname'=&gt;urlencode($first_name) ,
            'title'=&gt;urlencode($title) ,
            'company'=&gt;urlencode($institution) ,
            'age'=&gt;urlencode($age) ,
            'email'=&gt;urlencode($email) ,
            'phone'=&gt;urlencode($phone)
        ); 
//url-ify the data for the POST
foreach($fields as $key=&gt;$value) { $fields_string .= $key.'='.$value.'&amp;' ; }
rtrim($fields_string ,'&amp;') ;
//open connection
$ch = curl_init() ;
//set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL,$url) ;
curl_setopt($ch, CURLOPT_POST,count($fields)) ;
curl_setopt($ch, CURLOPT_POSTFIELDS,$fields_string) ;
//execute post
$result = curl_exec($ch) ;
//close connection
curl_close($ch) ;

本文章来给大家介绍一个PHP mysql事务回滚操作实例,有需要了解事物回滚的朋友可参考。操作方法很简单。

MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理!其他的类型是不支持的!

 代码如下 复制代码
public function insertUser ($userArray){
  foreach ($userArray as $key => $value) {
   @$field  .= "$key,";
   @$content .= "'$value',";
  } 
  $field  = ereg_replace(',$', '', $field);
  $content = ereg_replace(',$', '', $content);
 
  $db = db_connect();  //连接数据库
 
  $db->autocommit(FALSE); //设置为非自动提交——事务处理
 
  $sql1  = "INSERT INTO t_user (".$field.") VALUES (".$content.")";
  $result1 = $db->query($sql1);
 
  $sql2  = "INSERT INTO t_userpost (f_username) VALUES ('".$userArray['f_username']."')";
  $result2 = $db->query($sql2);
 
  if ($result1 && $result2) {
   $db->commit();  //全部成功,提交执行结果
   echo '提交';
  } else {
   $db->rollback(); //有任何错误发生,回滚并取消执行结果
   echo '回滚';
  }
  $db->close();
}
php备份mysql我们需借助于系统的计划任务功能,下面我来介绍在linux中php备份mysql实例方法。

#将所有备份文件备份到指定的目录,如/backup/mysql_data_backup

 代码如下 复制代码

mkdir /backup/mysql_data_backup -p
cd /backup/mysql_data_backup
wget /backmysql.txt -O backmysql.php
chmod +x backmysql.php
crontab -e

添加一行任务

 代码如下 复制代码
0 13 * * * /usr/bin/php /backup/mysql_data_backup/backmysql.php

表示在每天晚上0点13分用php执行备份命令

 

 代码如下 复制代码
#!/usr/bin/php
< ?php
 
//产生保存目录
$path = dirname(__FILE__) . '/' .date("Ym");
$filename = sprintf("%s/%s.sql.gz", $path, date("YmdHis"));
 
if(!is_dir($path))
        mkdir($path);
 
//导出并压缩所有数据库
$cmd = sprintf("/usr/bin/mysqldump -uroot -ppassword --all-databases | /bin/gzip > %s", $filename);
echo "backuping...n";
`$cmd`;
echo "backup done.n";

注意,这里只是计划信息处理了,如果要执行php文件我们需要自己写一个即可。

标签:[!--infotagslink--]

您可能感兴趣的文章: