表中有超过200k行,脚本需要超过20秒才能加载

时间:2012-02-27 20:57:06

标签: php mysql time pageload

我一直在为一家专门为他们的业务开发此应用程序的公司编辑脚本,现在他们来找我并希望进行一些升级。整个应用程序使用PHP和MySQL,减去几个Python脚本,每天将200k条记录导入数据库。我的问题是我需要允许根据每个记录的事件类型对每个记录进行分类和编辑。唯一的方法是通过每个记录中嵌入的URL,因为它是唯一真正独特的值。成功地解决了这个问题,但现在页面脚本需要永远(24秒)才能加载。

有人可以帮助我优化这段代码吗?

$notesq = mysql_query("SELECT * FROM `campaign_event_detail_v2` WHERE `call_recording_url`<>'' AND `event_type_name`='Call'") or die(mysql_error());
while($cnD = mysql_fetch_array($notesq)) {
$callid=$cnD[0];
$getD = mysql_query("SELECT campaign_notes.note, campaign_categories.category FROM campaign_notes LEFT JOIN campaign_categories ON campaign_notes.cid = campaign_categories.cid WHERE campaign_notes.cid='".$cnD['call_recording_url']."' OR campaign_categories.cid='".$cnD['call_recording_url']."'");
$getData = mysql_fetch_row($getD);
    mysql_query("UPDATE `campaign_event_detail_v2` SET `note`='".$getData[0]."',`category_id`='".$getData[1]."' WHERE `id`='".$callid."'");

}

非常感谢您的帮助!

谢谢, Ĵ

4 个答案:

答案 0 :(得分:0)

您似乎可以改进此查询:

SELECT campaign_notes.note, campaign_categories.category
FROM campaign_notes
LEFT JOIN campaign_categories
  ON campaign_notes.cid = campaign_categories.cid
WHERE campaign_notes.cid = {$cnD['call_recording_url']}
  OR campaign_categories.cid = {$cnD['call_recording_url']}

对此:

SELECT campaign_notes.note, campaign_categories.category
FROM campaign_notes
LEFT JOIN campaign_categories
  ON campaign_categories.cid = campaign_notes.cid
WHERE campaign_notes.cid = {$cnD['call_recording_url']}

答案 1 :(得分:0)

我认为你可以在一个查询中管理这个:

UPDATE campaign_event_detail_v2 d
LEFT JOIN campaign_notes n ON n.cid = d.call_recording_url
LEFT JOIN campaign_categories c ON c.cid = n.cid
SET d.note = n.note, d.category_id = c.category
WHERE d.call_recording_url != '' AND d.event_type_name = 'Call'

根据我的理解,我不能100%确定这是否是正确的逻辑。如果不是,我必须道歉。但是,我的观点是:您可以在一个查询中完成所有操作。

您可能应该在event_type_namecategory_idcid等列上添加索引(如果它们尚未存在)。它不会影响您的脚本,但需要一些时间来执行,具体取决于您的表中有多少条记录。

此外,最好使用triggers而不是在每次请求时执行此操作。

答案 2 :(得分:0)

这样的事情:

SELECT campaign_notes.note, 
   campaign_categories.category 
FROM campaign_event_detail_v2 AS detail
LEFT JOIN campaign_notes ON campaign_notes.cid = detail.call_recording_url 
LEFT JOIN campaign_categories ON campaign_notes.cid = campaign_categories.cid 
          AND campaign_notes.cid = detail.call_recording_url
WHERE detail.call_recording_url<>'' 
AND detail.event_type_name='Call'
AND campaign_notes.cid IS NOT NULL -- filters any from campaign notes that are empty
AND campaign_categories.cid IS NOT NULL -- filters any from campaign categories that are empty;

这会从与call_recording_url匹配的注释和类别以及过滤器中获取网址。然后它会过滤掉左连接中不匹配的任何内容(is null check)。如果仍然太慢,还有其他优化方法。然后你应该能够遍历并执行更新语句。

我还会尝试索引您正在加入的ID,尤其是call_recording_url,如果这是一个字符串,则搜索时间会更长。

答案 3 :(得分:-1)

我会为此创建一个存储过程,我会根据查询创建一些新的索引(例如,一个索引:call_recording_url,event_type_name)。

当然 - 你可以通过将它们只混合到一个来创建一个更好的查询。