在进行大循环时,我总是遇到PHP问题。我把它拆分成非常小的循环,当我们谈论的是大数字时,它会做几百次。
这是我现在正在使用的一个例子:
$stmt = $GLOBALS['link']->prepare('SELECT * FROM tracking_redirect');
$stmt->execute();
$tracking = new tracking();
while($click = $stmt->fetch()){
$tracking->checkClickIP($click['blogid'], $click['campaignid'], $click['id'], $click['ipaddress']);
}
tracking_redirect是一个表格,其中包含有关将哪些用户重定向到哪个网站的大量信息。我保存了诸如ipaddress,cookie-data,用户的日期和id之类的数据。该表目前有大约60,000行。
checkClickIP()是一个检查点击/重定向是合法还是有效的函数。确保同一用户没有点击太多次的示例。
public function checkClickIP($userid, $campaignid, $clickid, $ipaddress = null) {
if(!isset($ipaddress)){
$ipaddress = $_SERVER['REMOTE_ADDR'];
}
$datestmt = $GLOBALS['link']->prepare('SELECT crdate FROM tracking_redirect WHERE id=:clickid');
$datestmt->execute(array('clickid' => $clickid));
$datestmt = $datestmt->fetch();
$stmt = $GLOBALS['link']->prepare('SELECT COUNT(*) as total FROM tracking_redirect WHERE ipaddress=:ipaddress AND campaignid=:campaignid AND blogid=:userid AND crdate<:clickdate');
$stmt->execute(array(
'ipaddress' => $ipaddress,
'campaignid' => $campaignid,
'userid' => $userid,
'clickdate' => $datestmt['crdate']
));
$totalclicks = $stmt->fetch();
//Same computer has clicked more than 5 times on the same campaign. ALERT WARNING!
if($totalclicks['total'] >= 5){
//Disable the click
$disable = $GLOBALS['link']->prepare('UPDATE tracking_redirect SET disabled=:disabled WHERE id=:clickid');
$disable->execute(array(
'disabled' => 1,
'clickid' => $clickid
));
//Send a warning to the user if this person clicked 5 times on the same campaign.
if($totalclicks['total'] == 5){
$stmt = $GLOBALS['link']->prepare('SELECT * FROM user_login_history WHERE userid=:userid AND usertype=:usertype AND ipaddress=:ipaddress AND date(visitdate) BETWEEN :startdate AND :currentdate LIMIT 1');
$stmt->execute(array(
'userid' => $userid,
'usertype' => 1,
'ipaddress' => $ipaddress,
'startdate' => date('Y-m-d', strtotime('-3 months')), //If user logged in 3 months ago or closer from this IP
'currentdate' => date('Y-m-d')
));
//The computer belongs to the blogger who published the ad. ALERT WARNING! USER CLICKING HIS OWN ADS
if($loginhistory = $stmt->fetch()){
//Send warning to user.
}
//The computer does not belong to the blogger, but it's suspicious behavior. ALERT WARNING! CHECK POST
else{
//Send warning to user.
}
}
}
}
我知道在While循环之外准备语句会更好。但我仍然希望能够使用函数并拥有干净的代码。这段代码只是我无法在没有服务器返回错误的情况下运行while循环的一个例子,因为它超时等等。
因此,请不要在这种情况下过于依赖细节。但请提供可应用于其他代码的一般信息。我能做些什么来做这种循环~10,000或〜100,000次?
答案 0 :(得分:3)
当我们处理大量数据时,这总是一个问题。我目前正在开发一种产品,有时在一个GO中更新20K记录。该软件的另一部分使用简单的LINQ查询,但无论是上传还是更新,甚至需要批量数据,我们总是使用存储过程。
在这方面,您可以查看此链接MySQL Stored Procedure vs. complex query