公司在做游戏服务器合并的时候,对大批量数据表做了合并操作,难免会出现数据格式不一致问题。根据玩家反映BUG排查,是因为某个模块下日志表出现了数据格式问题导致。

目前想到的是有两种方案解决,第一种就是把所有的日志表数据修复;第二种就是把程序逻辑修改一下,保证查找格式正确。

我的做法是想把所有数据修复一下,就从线上数据库拿了7000条数据在本地修改测试,保证无误再执行下一步计划。

由于想到数据量会很大,我这里也顺便实验了一下多进程效率和单进程效率的对比。下面看下代码,有很多需要优化的地方....这里只是简单的案例....  两个数据表在最下面会分享链接测试.....

多进程实例

<?php
//index.php
$start_memory = memory_get_usage(); //开始内存
echo '开始内存:' . $start_memory . "\r\n"; $start_time = microtime(true); //获取程序开始执行的时间 $mysqli = new mysqli();//实例化mysqli
$mysqli->connect('localhost','root','wt000000','up'); $all_uid_sql = 'select uid from zc_kapai_fashion_show_intensify_log group by uid'; $all_user_result = $mysqli->query($all_uid_sql);
while (!!$_row = $all_user_result->fetch_assoc()) {
$all_user[] = $_row['uid'];
} //引入文件
require 'up_sql.php'; //count($all_user) = 84
$x_count = ceil(count($all_user)/); //fork 9个进程 进程太多,可能会导致服务器系统资源耗尽而崩溃,所以必须控制进程数量
for($i = ; $i < $x_count; ++$i) {
$pids[$i] = pcntl_fork();
if($pids[$i] == -) {
die('fork error');
} else if ($pids[$i]) { //父进程逻辑
pcntl_wait($status, WNOHANG);
} else { //子进程逻辑
$start = $i * ;
$tmp_users = array_splice($all_user, $start, );
if (is_array($tmp_users) && !empty($tmp_users)) {
up_sql($tmp_users) ;
}
exit;
}
} $all_user_result->free();
$mysqli->close();                    //别忘了关闭你的"小资源"; $end_time = microtime(true); //获取程序执行结束的时间
$run_time = ($end_time - $start_time) * ; //计算差值 毫秒
echo "[页面执行时间:{$run_time}]毫秒" . "\r\n";
$end_memory = memory_get_usage();
echo '运行后内存:'. $end_memory . "\r\n"; echo '使用的内存:' . ($end_memory - $start_memory) . "\r\n";
echo '回到正常内存:'.memory_get_usage();
<?php
//up_sql.php
//修改语句的方法
function up_sql ($temp_users = []) { $mysqli = new mysqli();//实例化mysqli
$mysqli->connect('localhost','root','wt000000','up'); foreach ($temp_users as $u) {
$sql1 = 'select id,fid from zc_kapai_fashion_show_intensify_log where uid =' .$u;//创建一句SQL语句
$sql2 = 'select id from zc_kapai_own_fashion_show where uid =' . $u;//创建一句SQL语句 $result1=$mysqli->query($sql1);
$result2=$mysqli->query($sql2); $log = [];
$show = [];
while (!!$_row = $result1->fetch_assoc()) {
$log[] = $_row;
}
while (!!$_row = $result2->fetch_assoc()) {
$show[] = $_row;
}
$test = $show[]['id'];
$return_arr = [];
foreach ($log as $lv) {
foreach ($show as $sv) {
$num = intval(substr((string)$sv['id'], , )); //show id ,拿来对比log的fid
if ($num == $lv['fid'] ) {
$arr = [];
$log_len = strlen((string)$lv['fid']);
$cha = - $log_len;
if (intval($cha) > ) {
$tou = (string)(substr($test, , $cha));
$val = $tou. (string)$num;
}
$arr['id'] = $lv['id'];
$arr['to_val'] = $val;
$return_arr[] = $arr;
}
}
} foreach ($return_arr as $v) {
$sql = 'update zc_kapai_fashion_show_intensify_log set fid = ' . $v['to_val'] . ' where id =' .$v['id'];
$mysqli->query($sql);
} }
$result1->free();//释放查询内存(销毁)
$result2->free();//释放查询内存(销毁)
$mysqli->close();//别忘了关闭你的"小资源";
}

Linux下Cli模式运行index.php,查看结果

# php index.php
开始内存:
[页面执行时间:160.7940196991]毫秒
运行后内存:
使用的内存:
回到正常内存:

单进程实例

<?php
//index.php $start_memory = memory_get_usage(); //开始内存
echo '开始内存:' . $start_memory . "\r\n";
$start_time = microtime(true); //获取程序开始执行的时间 $mysqli=new mysqli();//实例化mysqli
$mysqli->connect('localhost','root','wt000000','up'); $all_uid_sql = 'select uid from zc_kapai_fashion_show_intensify_log group by uid';
$all_user_result =$mysqli->query($all_uid_sql); while (!!$_row = $all_user_result->fetch_assoc()) {
$all_user[] = $_row['uid'];
}
foreach ($all_user as $u) {
$sql1='select id,fid from zc_kapai_fashion_show_intensify_log where uid =' .$u;
$sql2='select id from zc_kapai_own_fashion_show where uid =' . $u; $result1=$mysqli->query($sql1);//执行sql语句把结果集赋给$result
$result2=$mysqli->query($sql2);//执行sql语句把结果集赋给$result $log = [];
$show = [];
while (!!$_row = $result1->fetch_assoc()) {
$log[] = $_row;
} while (!!$_row = $result2->fetch_assoc()) {
$show[] = $_row;
}
$test = $show[]['id'];
$return_arr = [];
foreach ($log as $lv) {
foreach ($show as $sv) {
$num = intval(substr((string)$sv['id'], , )); //show id ,拿来对比log的fid
if ($num == $lv['fid'] ) {
$arr = [];
$log_len = strlen((string)$lv['fid']);
$cha = - $log_len;
if (intval($cha) > ) {
$tou = (string)(substr($test, , $cha));
$val = $tou. (string)$num;
}
$arr['id'] = $lv['id'];
$arr['to_val'] = $val;
$return_arr[] = $arr;
}
}
} foreach ($return_arr as $v) {
$sql = 'update zc_kapai_fashion_show_intensify_log set fid = ' . $v['to_val'] . ' where id =' .$v['id']; $mysqli->query($sql);
} } $result1->free(); //释放查询内存(销毁)
$result2->free(); //释放查询内存(销毁)
$all_user_result->free();
$mysqli->close(); //别忘了关闭你的"小资源"; $end_time = microtime(true); //获取程序执行结束的时间
$run_time = ($end_time - $start_time) * ; //计算差值 毫秒
echo "[页面执行时间:{$run_time}]毫秒" . "\r\n";
$end_memory = memory_get_usage();
echo '运行后内存:'. $end_memory . "\r\n"; echo '使用的内存:' . ($end_memory - $start_memory) . "\r\n";
echo '回到正常内存:'.memory_get_usage();

Linux下Cli模式运行index.php,查看结果

# php index.php
开始内存:
[页面执行时间:9905.3988456726]毫秒
运行后内存:
使用的内存:
回到正常内存:

测试结果明显对比,内存和执行时间....这里只是简单测试。

两个数据表

链接:https://pan.baidu.com/s/1ursYdiFB5wCbUf2mfBnWUA 密码:zhta

PHP多进程非阻塞模式下结合原生Mysql与单进程效率测试对比的更多相关文章

  1. socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto

    socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...

  2. 非阻塞模式下,虽然connect出错,但是getsockopt取得的错误却是0的问题

    调试项目代码时,发现了一个奇怪问题,记录如下: 非阻塞模式下,connect发起建链,返回-1(这在非阻塞模式下是很正常的现象).然后将该socket的写事件进行监听,在写事件触发后,getsocko ...

  3. Socket 阻塞模式和非阻塞模式

    阻塞I/O模型: 简介:进程会一直阻塞,直到数据拷贝 完成 应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好. 如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空间,IO函数返 ...

  4. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值(转载)

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值  ...

  5. 看到关于socket非阻塞模式设置方式记录一下。

    关于socket的阻塞与非阻塞模式以及它们之间的优缺点,这已经没什么可言的:我打个很简单的比方,如果你调用socket send函数时: 如果是阻塞模式下: send先比较待发送数据的长度len和套接 ...

  6. 深入 CSocket 编程之阻塞和非阻塞模式

    有时,花上几个小时阅读.调试.跟踪优秀的源码程序,能够更快地掌握某些技术关键点和精髓.当然,前提是对这些技术大致上有一个了解. 我通过几个采用 CSocket 类编写并基于 Client/Server ...

  7. UNIX网络编程——关于socket阻塞与非阻塞情况下的recv、send、read、write返回值

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有 区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回 ...

  8. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值---部分内容可能不确切,待讨论

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值  ...

  9. 非阻塞模式ServerSocketChannel 聊天室服务器端

    import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import ja ...

随机推荐

  1. 2019.03.23 Http

    自己也要分清楚  看清楚 request,response 一个是请求  一个是相应 行 头    之间还有个空行    体 HttpRequest请求对象(只读) 当用户访问一个视图函数时,Djan ...

  2. xcode 报错Failed to load project at xxxx ,incompatible project version

    错误原因: 由于工程是低版本的Xcode建立的,在使用高版本的Xcode打开时会出现编译不了工程. 解决方法: 鼠标右击.xcodeproj文件 —>显示包内容 —>打开project.p ...

  3. tcpdump 选项及过滤规则

    tcpdump tcp -i eth1 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap (1)t ...

  4. lnmp----------lnmp集成环境使用lnmp安装包安装lnmp集成环境的步骤

    1.先看下screen -S lnmp 命令是否存在,不存在则安装.这个是个什么东东呢?百度一下( GNU Screen是一款由GNU计划开发的用于命令行终端切换的自由软件.用户可以通过该软件同时连接 ...

  5. js中call,caller,callee,aplly

    1.函数的caller属性 (1).区分函数是在函数体调用还是顶层代码中调用:顶层中调用函数,该函数的caller属性返回null,在函数中调用,会返回调用发i函数的函数: <script> ...

  6. VS.C#如何向数据数据库中存入和读取图片的

    写入图片部分代码:假设图片为 test.gifbyte [] bytes = File.ReadAllBytes(@"c:\test.gif");SqlConnection con ...

  7. SQL中的关联更新和关联删除

    在SQL中,经常用到关联查询,比如select a.* from A a inner join B b on a.PId=b.FId where 条件,SQL中也支持类似的关联更新和关联删除. 关联更 ...

  8. UVa-116 Unidirectional TSP 单向旅行商

    题目 https://vjudge.net/problem/uva-116 分析 设d[i][j]为从(i,j)到最后一列的最小开销,则d[i][j]=a[i][j]+max(d[i+1][j+1], ...

  9. python3(socket 实现udp,tcp套接字编程)

    #coding=utf-8 #客户端程序TCP 连接 import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connec ...

  10. discuz用户组

    非公众用户组当用户组设置为“非公众用户组”时,无论是以主用户组的形式,还是以扩展用户组的形式,均只能由管理员手工将用户加入本组. 公众用户组当本用户组设置为“公众用户组”,且用户当前所在的用户组被允许 ...