扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
没看到你的全选按纽呢?
创新互联公司专注为客户提供全方位的互联网综合服务,包含不限于网站制作、网站设计、城区网络推广、小程序制作、城区网络营销、城区企业策划、城区品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联公司为所有大学生创业者提供城区建站搭建服务,24小时服务热线:028-86922220,官方网址:www.cdcxhl.com
不过这个问题 跟php代码没关系哈
你先做下静态的全选功能吧
我只针对你这个做优化吧。。
第一个不要用select * 这样的sql语句,你需要什么字段就写哪些字段
都需要的话,你都写出来,select * 效率很低的。。
第二个如果说你的后台中对这些数据的变动不是很频繁
然后你可以将查询结果存入memcahe中
我写一段伪代码
$mem_key="all";
$res = $memcache-get($mem_key);
//如果没有存入memcache中
if (empty($res){
//sql语句可以用left jion on关联查询
$aaa="select b.字段1,b.字段2...from btb as b left jion tb as b.id=t.id";
$bb=$mysql-_query($aaa);
while(!!$_rows=$mysql-_fetch_array_list($bb)){
//do something
$res ....
}
//结果存入memecahed中
$memcache-set($mem_key,$res,0,超时时间);
}
$res就是你获取的结果。。
你这段代码基本可以这样。。
?php
$str = HHH
region=BJ
162.105/16, 166.111/16, 202.4.128/19,
202.112.64/18, 202.112.128/17, 202.113/16, 202.204/14, 210.31/16, 211.68/16, 211.71/16,
211.81/16, 211.82/16, 219.242/16, 219.243.0/17, 219.243.128/18,
219.224.0/17, 219.224.128/18, 219.225/16, 219.226/16, 222.28/14,
222.199/16, 59.64/14, 203.91.120/21, 121.193/16, 121.194/15,
118.228/15, 118.230/16, 121.52.160/19, 115.24/14
region=XA
202.117/16, 202.200/15, 210.26/15, 218.195/16, 219.244/14, 222.23/16, 222.24/15,
59.74/15, 59.76/16, 120.95/16, 115.154/15
region=CD
202.115/16, 202.202/15, 210.40/15, 211.83/16, 218.194/16, 219.221/16, 222.18/15, 222.196/15, 222.198/16, 121.48/15, 120.94/16, 113.54/15
region=GZ
202.38.192/18, 202.116/16, 202.192/15, 210.36/14, 211.66/16, 218.192/16, 219.222/15, 219.227/16,
222.16/15, 222.200/14, 125.216/15, 125.218/16, 116.56/15, 116.13/16,
110.64/15
region=WH
202.114/16, 202.196/15, 210.42/15, 211.69/16, 211.67/16, 211.84/15, 218.196/14, 222.20/15, 222.22/16, 59.68/14,
125.219/16, 125.220/15, 122.204/14, 115.156/15, 115.158/16
region=NJ
202.38.64/19, 202.119/16, 202.194/15, 210.44/15, 210.28/15, 211.64/15, 211.70/16, 211.86/15, 219.218/15, 219.230/15,
222.192/14, 222.206/15, 58.192/15, 121.248/14,
114.212/15, 114.214/16
region=SH
202.120/15, 210.32/14, 211.80/16, 218.193/16, 219.220/16, 219.228/15, 222.204/15, 59.77/16, 59.78/15,
58.198/15, 121.192/16, 111.186/15
region=SY
202.118/16, 202.198/15, 210.46/15, 210.30/16, 219.216/15, 222.26/15, 59.72/15, 125.222/15,
58.154/15, 118.202/15
region=MISC
202.38.96/19, 202.38.140/23, 202.38.184/21, 202.127.216/21, 202.127.224/19, 202.112.0/18, 210.25.128/18,
219.243.192/18, 219.224.192/18, 210.25.0/17
region=CIS
58.194/15, 58.200/13
region=TTN
58.196/15
region=TEIN2
202.179.240/20
HHH;
$reg = '/(?=region=)(\w+)(.+?)(?=region=)/s';
preg_match_all($reg, $str, $matches);
//echo nl2br(var_export($matches, true));
$result = array();
foreach($matches[1] as $key=$val)
{
$header = array("$val");//BJ
$body = explode(',', $matches[2][$key]);//162.105/16, 166.111/16, 202.4.128/19...
$result[] = array_merge($header, $body);//merge array
}
//match last
$str2 = substr($str, strrpos($str, 'region='));
$reg2 = '/(?=region=)(\w+)(.+)/s';
preg_match($reg2, $str2, $matches2);
$tmp = explode(',', $matches2[2]);
array_unshift($tmp, $matches2[1]);
$result[] = $tmp;
echo 'hr';
echo nl2br(var_export($result, true));
?
//换行符不知怎么弄的,就是找不到,所以多出了空格。
你用网页的方式,让人点击,服务器采集,简直是弱爆了。每个人的点击循环1000次,来个100人同时点,你要用的是普通的虚拟机就不行了。
最好是换种方式实现,不要通过网页进行采集。
可以非常简单的在数据库的表,创建一个采集队列,后台执行一个crontab的计划任务,去完成队列里的采集任务。
你是cli模式还是cgi模式?cli模式不用设默认就是无时间限制,cgi默认是有30秒超时限制。
你可以先看看每次中断是固定时长,还是固定次数;也可以多打日志,每次循环都输出些参考参数如循环条件、内存使用等信息,再分析哪些可能导致程序中断的原因。
我前几天有一个面试,面试题就是有这样一道题。先把自己的思路说一下,因为信息量非常的大,所以我采用了分表,分成24张表,每个小时一张,虽然凌晨时刻的表可能很少数据,但这样sum字段的问题就容易解决了,我理解的sum字段是一个小时同一个用户在相同的环境的登陆次数。这样理解不知对否,请网友自行甄辨。然后我通过PHP中的fgets函数一行一行的数据取出,入表。实验了几万条数据是没有问题的,但是上亿条数据可能够呛。这一点也请网友注意,我也是新手。只是看到这里没有答案,给大家一个参考。废话不多,看流程:
日志文件(access.log)格式:
200 /alipeng.gif?zoneid=2bannerid=44clentid=6materialid=64redirect=http%3a%2f%2f;time=1384444800.832ip=127.0.0.1user_agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.48 Safari/537.36utrace=a6dbdd2f6a37b946165b7ae98dcd4f79
502 /alipeng.gif?zoneid=2bannerid=44clentid=6materialid=64redirect=http%3a%2f%2f;time=1384444800.904ip=127.0.0.1user_agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.48 Safari/537.36utrace=a6dbdd2f6a37b946165b7ae98dcd4f79
配置文件cfg.php:
define(HOST,'localhost');//主机名
define(USER,'root');//数据库账号
define(PASS,'111111');//数据库密码
define(DBNAME,'test');//所用的数据库
define(CHARSET,'utf8');//使用的字符集
具体代码test.php:
?php
header("content-type:text/html;charset=utf-8");
require './cfg.php';
$link = mysql_connect(HOST,USER,PASS) or die('连接数据库失败');
//程序中自动建库和建表,这样一定程度上拖慢了程序的速度
//创建数据库
$crdb="create database if not exists ".DBNAME;
if(!mysql_query($crdb)){
die('创建数据库失败');
}
//链接数据库
mysql_select_db(DBNAME) or die('选择数据库失败');
mysql_set_charset(CHARSET);
//因为数据量很大我将数据按小时分表,分成24个表,每小时一个表,这样num字段的值也好做统计
//数据循环建表
for($i=0;$i24;$i++){
if($i10){
$tbhz='0'.$i;//如果前10张表,表后缀应该是00-09
}else{
$tbhz=$i;
}
$ctbsql="create table if not exists logininfo_{$tbhz}(
id int not null auto_increment primary key,
zoneid int not null default 0,
bannerid int not null default 0,
clentid int not null default 0,
materialid int not null default 0,
redirect char(200) not null default '',
time char(16) not null default '',
user_agent char(200) not null default '',
utrace char(32) not null default '',
sum int not null default 0
)TYPE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";
mysql_query($ctbsql);
}
//打开文件
$file=fopen("./access.log",'r') or die("打开文件失败");
//对文件内容进行循环,直到文件末尾才停止
while (!feof($file)){
//每次读取一行
$line = fgets($file,1024);
//状态是200的进行写入数据库操作
if(preg_match('/^200/',$line)){
$pinfo=parse_url($line);//url信息
$ext=$pinfo['query'];//取得传递的各个参数
$parray=explode('',$ext);//根据分解为数组
//因为分解为数组后并不是要的值,所以要对值进行一次截取,将等号及等号左边的都去掉
foreach($parray as $val){
$narray[]=ltrim(strstr($val,'='),'=');
}
$narray[8]=rtrim($narray[8],'_');
//截取时间的秒数
$getmun=substr($parray[5],5,10);
$time=date('Y-m-d H',$getmun);//将秒数转化为时间类型。
//得到表后缀
$tbhz=date('H',$getmun);
$sql="insert into logininfo_{$tbhz} values(null,'{$narray[0]}','{$narray[1]}','{$narray[2]}','{$narray[3]}','{$narray[4]}','{$time}','{$narray[7]}','{$narray[8]}',0)";
//echo $sql;
$res=mysql_query($sql);//执行插入
if(!$res || !mysql_affected_rows()0){
die('写入数据库失败');
}
unset($narray);//循环一次将narray销毁,为下一次循环做准备
//var_dump(parse_url($line)['query']);
}
}
fclose($file);//关闭
//因为sum字段还是0,下面代码段需要处理sum字段的值
//24张表循环处理
for($i=0;$i24;$i++){
if($i10){
$tbhz='0'.$i;//如果前10张表,表后缀应该是00-09
}else{
$tbhz=$i;
}
//该sql语句是把同一个小时内,并且符合条件相等的登陆的总次数和需要的登陆信息查出,为下面修改sum做准备
$sql="SELECT COUNT('zoneid') AS sum,zoneid,bannerid,clentid,materialid,redirect,user_agent,utrace FROM logininfo_{$tbhz} GROUP BY zoneid,bannerid,clentid,materialid,redirect,user_agent,utrace";
//发送查询sql
$res=mysql_query($sql);
if($res mysql_num_rows($res)0){
while($row=mysql_fetch_assoc($res)){
//修改sum字段,即同一小时内的登陆次数
$upsql="update logininfo_{$tbhz} set sum='{$row['sum']}' where zoneid='{$row['zoneid']}' and bannerid='{$row['bannerid']}' and clentid='{$row['clentid']}' and materialid='{$row['materialid']}' and redirect='{$row['redirect']}' and user_agent='{$row['user_agent']}' and utrace='{$row['utrace']}'";
//发送修改sql,执行修改sum
$upres=mysql_query($upsql);
if(!$upres){
die('修改登陆sum失败');
}
}
}
}
echo '数据成功入表';
使用说明:
将配置文件cfg.php中的连接数据库账号、密码修改为自己本机的(默认新增的库名是test)
直接运行test1.php
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流