如何减少执行时间?

时间:2011-10-01 23:52:31

标签: php facebook facebook-graph-api

我有一个Facebook应用程序,用户可以在篮球比赛中下注(猜测胜利者,差异,mvp和最佳射手)。

我在游戏中保留一张桌子,一张包含用户的ID,另一张包含赌注。

如果你猜对了,那么你得到1分。如果你认为差异正确,你得到5分。如果你猜对了你的mvp你得到3分,而得分最高也是如此。

现在我有一个文件可以创建一个包含所有用户及其观点的表格:

        <table>
        <tr>
            <td></td>
            <td>
                Name
            </td>
            <td>
                Points
            </td>
        </tr>
        <?php
            $selectusers = $db->query("SELECT * FROM `predictorusers`");
            $c = 0;
            while ($appuser = $db->fetchRows($selectusers))
            {
                try
                {
                    $profile = $facebook->api('/'.$appuser['userid']);
                } catch (FacebookApiException $e) {
                    continue;
                }
                $c++;

                $points = 0;

                $selectbets = $db->query("SELECT * FROM `predictor` WHERE `userid`='{$profile['id']}'");
                while ($bet = $db->fetchRows($selectbets))
                {
                    $selectgame = $db->query("SELECT * FROM `schedule` WHERE `id`='{$bet['gameid']}'");
                    $game = $db->fetchRows($selectgame);

                    if ($bet['winner'] == 1 && $game['homescore'] > $game['awayscore'])
                    {
                        $points = $points + 1;

                        if (($game['homescore'] - $game['awayscore']) == $bet['diff'])
                            $points = $points + 5;
                    }
                    elseif ($bet['winner'] == 2 && $game['awayscore'] > $game['homescore'])
                    {
                        $points = $points + 1;

                        if (($game['awayscore'] - $game['homescore']) == $bet['diff'])
                            $points = $points + 5;
                    }

                    $selectmvprkg = $db->query("SELECT MAX(`rkg`) FROM `boxscore` WHERE `game`='{$game['id']}'");
                    $mvprgk = $db->fetchRows($selectmvprkg);

                    $selectmvp = $db->query("SELECT * FROM `boxscore` WHERE `rkg`='{$mvprkg['rkg']}'");
                    while ($mvp = $db->countRows($selectmvp))
                    {
                        if ($mvp['player'] == $bet['mvp'])
                            $points = $points + 3;
                    }

                    $selecttopscorerpts = $db->query("SELECT MAX(`pts`) FROM `boxscore` WHERE `game`='{$game['id']}'");
                    $topscorerpts = $db->fetchRows($selecttopscorerpts);

                    $selecttopscorer = $db->query("SELECT * FROM `boxscore` WHERE `pts`='{$topscorerpts['pts']}'");
                    while ($topscorer = $db->fetchRows($selecttopscorer))
                    {
                        if ($topscorer['player'] == $bet['topscorer'])
                            $points = $points + 5;
                    }
                }
        ?>
        <tr>
            <td>
                <?php echo $c; ?>
            </td>
            <td>
                <?php echo $profile['name']; ?>
            </td>
            <td>
                <?php echo $points; ?>
            </td>
        </tr>
        <?php
            }
        ?>
    </table>

唯一的问题是,脚本需要超过30秒才能完全执行,因此服务器会停止执行并发送错误信息:

  

致命错误:第37行的 * 超出了30秒的最长执行时间

有谁知道如何防止这种情况发生?

编辑:

看看这个包含0个api调用的文件:

        <table>
        <tr>
            <td></td>
            <td>
                Name
            </td>
            <td>
                Points
            </td>
        </tr>
        <?php
            $selectusers = $db->query("SELECT * FROM `predictorusers`");
            $c = 0;
            while ($appuser = $db->fetchRows($selectusers))
            {
                $c++;

                $points = 0;

                $selectbets = $db->query("SELECT * FROM `predictor` WHERE `userid`='{$appuser['userid']}'");
                while ($bet = $db->fetchRows($selectbets))
                {
                    $selectgame = $db->query("SELECT * FROM `schedule` WHERE `id`='{$bet['gameid']}'");
                    $game = $db->fetchRows($selectgame);

                    if ($bet['winner'] == 1 && $game['homescore'] > $game['awayscore'])
                    {
                        $points = $points + 1;

                        if (($game['homescore'] - $game['awayscore']) == $bet['diff'])
                            $points = $points + 5;
                    }
                    elseif ($bet['winner'] == 2 && $game['awayscore'] > $game['homescore'])
                    {
                        $points = $points + 1;

                        if (($game['awayscore'] - $game['homescore']) == $bet['diff'])
                            $points = $points + 5;
                    }

                    $selectmvprkg = $db->query("SELECT MAX(`rkg`) FROM `boxscore` WHERE `game`='{$game['id']}'");
                    $mvprgk = $db->fetchRows($selectmvprkg);

                    $selectmvp = $db->query("SELECT * FROM `boxscore` WHERE `rkg`='{$mvprkg['rkg']}'");
                    while ($mvp = $db->countRows($selectmvp))
                    {
                        if ($mvp['player'] == $bet['mvp'])
                            $points = $points + 3;
                    }

                    $selecttopscorerpts = $db->query("SELECT MAX(`pts`) FROM `boxscore` WHERE `game`='{$game['id']}'");
                    $topscorerpts = $db->fetchRows($selecttopscorerpts);

                    $selecttopscorer = $db->query("SELECT * FROM `boxscore` WHERE `pts`='{$topscorerpts['pts']}'");
                    while ($topscorer = $db->fetchRows($selecttopscorer))
                    {
                        if ($topscorer['player'] == $bet['topscorer'])
                            $points = $points + 5;
                    }
                }
        ?>
        <tr>
            <td>
                <?php echo $c; ?>
            </td>
            <td>
                <?php echo $app['userid']; ?>
            </td>
            <td>
                <?php echo $points; ?>
            </td>
        </tr>
        <?php
            }
        ?>
    </table>

同样的事情发生了。

3 个答案:

答案 0 :(得分:2)

我建议以某种方式缓存API调用的结果,这样每次页面加载时都不必为每个用户调用API。

您可能还想查看Facebook API functions that allow you to request data for more than a single user at a time - 为结果集中的所有用户进行一次API调用比为每个用户进行单独的API调用要快得多。

另外一般情况下,在多个级别的循环中嵌套查询是一个坏主意 - 尝试减少您正在运行的查询总数。

答案 1 :(得分:1)

您已深入嵌套查询3。代码中的嵌套查询始终是一个红色标记(在极少数情况下是必要的)。对于预测器中的每条记录,您都在查询预测器中的记录。然后,对于预测器中的每个查询,您将对计划和boxscore运行查询(3次)。

这就是问题所在,你运行的查询太多了。您应该使用JOIN并将数据缩小到特定信息。您似乎在查询所有数据。你可以将它降低到每个用户1个查询,甚至只用一个用户ID过滤器查询。

答案 2 :(得分:1)

  1. 请不要使用select *,而是使用特定的列名称。
  2. 请使用单次提取避免嵌套的sql语句,并在数组中保存数据以进行遍历。
  3. 尝试使用XDebug Profiler来确定脚本的哪个部分需要更多时间来加载。