首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >优化PHP / MySQL脚本以减少服务器使用

优化PHP / MySQL脚本以减少服务器使用
EN

Stack Overflow用户
提问于 2015-02-13 14:52:23
回答 1查看 293关注 0票数 0

我有一个每日页面浏览量超过1'000'000的网站和一个php脚本,可以在每一页上显示2-3条横幅广告,并计算印象。

来计算印象,在每个横幅之后有一个图像:

<img src="https://example.com/impression.php?client=ABC&banner=XYZ" width=1 height=1>

这是印象脚本的一个例子:

代码语言:javascript
运行
复制
require('global.php'); // connect to mysql, read default settings, etc

if( isset( $_GET['client'] ) ) && !empty( $_GET['client'] ) ) { $client = secure( $_GET['client'] ); } else { die('error param'); }
if( isset( $_GET['banner'] ) ) && !empty( $_GET['banner'] ) ) { $banner = secure( $_GET['banner'] ); } else { die('error param'); }

$check_client = mysqli_query( $con, "SELECT id FROM clients WHERE id = '$client' AND status = 1 LIMIT 1" ) or die( 'error mysql' );
if( mysqli_num_rows( $check_client ) == 0 ) { die('error client'); }

$check_banner = mysqli_query( $con, "SELECT campaign_id FROM banners WHERE id = '$banner' AND status = 1 LIMIT 1" ) or die( 'error mysql' );
if( mysqli_num_rows( $check_banner ) == 0 ) { die('error banner'); }    
$read_campaign_id = mysqli_fetch_array( $check_banner ); 

$check_campaign = mysqli_query( $con, "SELECT id FROM campaigns WHERE id = '$read_campaign_id[0]' AND status = 1 LIMIT 1" ) or die( 'error mysql' );
if( mysqli_num_rows( $check_campaign ) == 0 ) { die('error campaign' );  }

$check_unique = mysqli_query( $con, "SELECT id FROM impressions WHERE datetime LIKE '$today%' AND banner = '$banner' AND ip = '$ip' ORDER BY datetime DESC LIMIT 1" ) or die( 'error mysql');
if( mysqli_num_rows( $check_unique ) == 1 ) { $unique = 0; } else { $unique = 1; }

mysqli_query( $con, "INSERT INTO impressions ( client, campaign, banner, datetime, unique, ip, page ) VALUES ( '$client', '$read_campaign_id[0]', '$banner', '$now', '$unique', '$ip', '$url' )" ) or die( 'error mysql' );

header( 'Content-type: image/png' );
header( $path . '/img/pixel.png' );
mysqli_close( $con );
exit;

在这种情况下,优化脚本和减少服务器上资源使用和并发连接的最佳方法?

  • 例如,是否可以将某个mysql查询合并到一个查询中?我觉得应该快得多,但我不确定.
  • 另一种可能的方法是将印象保存在CSV文件中,并且每2-5分钟在mysql上导入这个文件?但它只保存了一个查询..。

编辑:--这是mysql表结构(只包含本例中有用的字段) http://sqlfiddle.com/#!2/1ffe3/1

EN

回答 1

Stack Overflow用户

发布于 2015-02-13 17:01:53

是的,您可以在一个查询中运行所有的选择。

相当令人困惑的是(因为您只需要从每一行中提取一行,而且它们之间没有明显的关系),您可以使用笛卡儿积来完成这一任务。

您的模式很糟糕(像“$today%”这样的日期时间使用字符串来存储日期!)

当您只想查看是否存在任何行时,为什么要排序$check_unique的结果?

代码语言:javascript
运行
复制
SELECT clients.id AS client_id
, banner.campaign_id AS banner_campaign_id
, campaign_id
,(SELECT COUNT(*)
   FROM impressions 
   WHERE impressions.datetime LIKE '$today%' 
   AND impressions.banner = '$banner' 
   AND ip = '$ip' 
   LIMIT 1) AS check_unique
FROM clients
INNER JOIN banners
INNER JOIN campaigns
WHERE clients.id = '$client' AND clients.status = 1
AND banners.id = '$banner' AND banners.status = 1
AND campaigns.id = '$read_campaign_id[0]' AND campaigns.status = 1
LIMIT 1

或者,您可以将其展开为一个联盟,但这是少得多的乐趣。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28502212

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档