我写了一个PHP脚本,它连接两个表来显示这种格式的信息:
Jane Doe
Phone: 082 980 9514
Home Loan Applications (Active) - 17/07/2013
Credit Report (Free Report) (Unsubscribed) 12/06/2013
你会注意到第一个和最后一个名字在输出的第一行,然后是电话号码,然后是他们订阅的邮件列表。列表旁边是状态。 “活动”表示如果用户已选择退出邮件列表,则在显示未订阅日期时,用户尚未取消订阅并仍处于活动状态。然后是订阅者注册日期到某个邮件列表。
以下是示例表格的链接: Tables
它可以正常工作,但需要永远完成,因为1个表中有大约76,000个记录,而另一个表中大约有100,000个记录。我想问一下如何优化代码以加快脚本的建议。
这是我写的当前代码:
$resultarray = array();
$rs4 = mysqli_query($con1,"SELECT interspire_customfield.subscriberid, interspire_customfield.fname, interspire_customfield.lname, interspire_customfield.phone, emailaddress, subscribedate, unsubscribed, interspire_customfield.listid, listname FROM `interspire_subscriber` INNER JOIN `interspire_customfield` ON interspire_subscriber.subscriberid = interspire_customfield.subscriberid GROUP BY emailaddress");
while($row4 = mysqli_fetch_array($rs4)) {
$resultarray[] = $row4['subscriberid'].",".$row4['fname'].",".$row4['lname'].",".$row4['phone'].",".$row4['emailaddress'];
}
foreach ($resultarray as $arrlist) {
$arr = explode(',', $arrlist);
$sid = $arr[0];
$frstname = $arr[1];
$lstname = $arr[2];
$pnum = $arr[3];
$emailadd = $arr[4];
echo $frstname." ".$lstname."<br />";
echo "Phone: ".$pnum."<br />";
$rs5 = mysqli_query($con1,"SELECT interspire_customfield.subscriberid, subscribedate, unsubscribed, interspire_customfield.listid, listname FROM interspire_subscriber INNER JOIN interspire_customfield ON interspire_subscriber.subscriberid = interspire_customfield.subscriberid WHERE interspire_subscriber.emailaddress = '$emailadd' GROUP BY interspire_subscriber.listid");
if (!$rs5) {
printf("Error: %s\n", mysqli_error($con));
exit();
}
while($row5 = mysqli_fetch_array($rs5)) {
$listname = $row5['listname'];
$subdate = $row5['subscribedate'];
$unsub = $row5['unsubscribed'];
if($unsub == "0"){
$stat = "Active";
}else{
$stat = date('d/m/Y', $unsub);
}
$subdt = date('d/m/Y', $subdate);
echo "* $listname ($stat) - $subdt <br />";
}
echo "<br />";
}
答案 0 :(得分:1)
如果在两个表中都有索引(如果没有,在两个字段的subscriberid上创建它),请尝试使用不带JOIN的查询:
SELECT
ic.subscriberid,
ic.fname,
ic.lname,
ic.phone,
ic.listid,
emailaddress,
subscribedate,
unsubscribed,
listname
FROM `interspire_subscriber` isub, `interspire_customfield` ic
WHERE isub.subscriberid = ic.subscriberid
GROUP BY emailaddress
使用缓冲区在打印前存储字符串。您可以将字符串值或数组与join()方法或ob_start一起使用。
答案 1 :(得分:1)
您的预期输出需要确定每个电子邮件地址的一组姓名和电话号码:但由于interspire_subscriber
将多个subscriberid
值与一个emailaddress
相关联,因此加入{ {1}}(包含姓名和电话号码数据)不是1:1;因此,电子邮件地址可能与多个不同的姓名和电话号码相关联。
您必须按interspire_customfield
对输出进行分组(可能无法满足您整理每个用户列表订阅的预期结果),或者您必须更改架构:任何此类更改必须包含一次性确定来自subscriberid
的值应与每个interspire_customfield
相关联。然后我会建议在emailaddress
上键入interspire_customfield
(并从该表中删除emailaddress
并从其中一个表中删除listid
,具体取决于它是否应与订阅者或订阅)。
进行这些更改后,您可以执行以下操作:
subscriberid
至于速度,您应该确保在$dbh = new PDO("mysql:dbname=$dbname;charset=utf8", $username, $password);
$qry = $dbh->query('
SELECT emailaddress,
c.fname, c.lname, c.phone,
s.subscribedate, s.unsubscribed, s.listname
FROM interspire_subscriber AS s
JOIN interspire_customfield AS c USING (emailaddress)
ORDER BY emailaddress, s.listid
');
if ($qry) {
echo '<ol>';
$row = $qry->fetch();
while ($row) {
$current_email = $row['emailaddress'];
echo '<li>',
htmlentities($row['fname']),' ',htmlentities($row['lname']),'<br/>',
'Phone: ',htmlentities($row['phone']),
'<ul>';
do {
$unsub = $row['unsubscribed'];
echo '<li>',htmlentities($row['listname']),
' (',$unsub ? 'Active' : date('d/m/Y', $unsub),')',
' - ',date('d/m/Y', $row['subscribedate']),
'</li>';
} while ($row = $qry->fetch() and $row['emailaddress'] == $current_email);
echo '</ul>',
'</li>';
}
echo '</ol>';
}
表上定义了interspire_subscriber
上的综合索引;以及(emailaddress, listid)
上UNIQUE
表上的interspire_customfield
索引。
虽然我们处于此状态,但您可能希望考虑是否需要(emailaddress)
(它似乎是非规范化的,因为它应该与其他表中的interspire_subscriber.listname
相关联)?您可能还希望考虑使用MySQL的本机时态数据类型而不是整数来存储时态值。