之前有几篇文章,说了最近tiandi在帮朋友做一个小项目,用于统计电话号码的,每次按需求从数据库里随机生成打包的电话号码,然后不停地让人打这些电话号码推销产品(小小鄙视一下这样的行为)。但是朋友要求帮忙,咱也不能不帮啊,是吧。程序两个星期前已经做好,测试完毕交工。前几天朋友来电说,每天导入电话号码的时间越来越长,有时候一万条记录就要半个小时以上,看看能不能想办法提高一下这个速度。
我理了一下思路,数据库结构很简单,可以认为就两个字段,一个字段存电话号码,另一字段存类别,类别分别为c,d,e等等,分别代表已经拨通过此电话,未拨通过此电话,未拨打过此电话等等状态,而整个程序逻辑是这样的:
■拿到一个txt文件,里面存的是电话号码
■通过程序将txt文件导入到mysql里
■导入的时候,检测txt里的电话号码是否和mysql里的重复,如果不重复,直接插入新记录,如果重复,就需要按照判断电话号码所属类别来进行更新。
由于每个txt里的电话号码导入时,都需要做一次比较,所以程序肯定会耗时一些,这里我们先撇开这个原因,因为本文章的标题是优化写入速度,那么程序什么时候会写入记录呢?通过上面的逻辑得知,在匹配数据库时,没有发现存在记录时会发生写入数据库操作(当然update也算,只是这里只讨论insert)。那么将上述逻辑转化为代码,差不多如下:
代码如下 | 复制代码 |
//$array为txt文件explode出来的数组,每一个为一个电话号码, $str为类型 |
以上代码完全正确,但是效率低下,当txt文件里包含了上万个电话号码时,即会有上万次的插入数据库操作,虽然每次的数据库写入操作都是很快的,但是上万条累计下来,这个执行时间不容忽视。tiandi简单的测试了一下插入15000万条记录,耗时差不多5分钟。如果再加上之前的逻辑判断等等过程,那么半个小时还真得不算少了。这样可不行,必须减少数据库库写入次数才对,于是上面代码变更为以下:
代码如下 | 复制代码 |
$sql2="INSERT INTO ".$usertable." (tel,type,updatetime) VALUES"; |
这样,整个写入操作只有1次,大大地缩短了执行时间,差不多10秒就搞定了15000条记录。好了,本文到此结束,如果你也遇上写入大量数据到mysql耗时长的问题时,不如试试本文的优化方式。
最近需要把一个以前的asp网站转换成php的,但php是与mysql而我的asp与mssql的,结果就需要把mssql数据导入到mysql数据库了,下面我自己写了一个实例还抄了一个实例都不错。实例一
代码如下 | 复制代码 |
<?php $conn = mssql_connect($hostname,$dbuser,$dbpasswd); //连接MSSQL { ?> |
参考代码二、
代码如下 | 复制代码 |
<?php $mssql_link = mssql_connect($db_host,$db_msuser,$db_mspass) or 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 = ”; while ($row = mssql_fetch_array($msquery,$mssql_link)){ $sql = echo $sql; $aa=mysql_query($sql, $mysql_link); if ($aa){ ?> |
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 |
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(); } |
#将所有备份文件备份到指定的目录,如/backup/mysql_data_backup
代码如下 | 复制代码 |
mkdir /backup/mysql_data_backup -p |
添加一行任务
代码如下 | 复制代码 |
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文件我们需要自己写一个即可。