如何提高从MySql数据库处理数据的速度

时间:2014-02-05 15:26:03

标签: php mysql performance pdo

我通过记录每分钟在线的人来监控服务器上的玩家活动。播放器列表存储为varchar字段中的单个逗号分隔字符串。

我让玩家选择一个日期来显示当天和那个月的在线人员。

该脚本运行良好并按预期执行,但是我需要花费很长时间来处理数据。目前加载页面大约需要10秒钟。

我的问题是:是否有更有效,更快捷的获取和显示数据的方式?

显示玩家活动的

This is the webpage

    if(isset($_POST['submit'])){

    $chosenDay   =$_POST['day'];
    $chosenMonth =$_POST['month'];
    $chosenYear  =$_POST['year'];
    ?>
<article id="intro">
    <div id="motd">
    <h2>Player Activity Graph</h2>
    <form class="form" action="activity.php" method="POST">
    <select name="year" class="date-select">
    <?php
        echo '<option value="'.$chosenYear.'" selected>'.$chosenYear.'</option>';
        for($i = 2013; $i<$currentYear; $i++){
            echo '<option value="'.$i.'">'.$i.'</option>';
        }
    ?>

    </select>
    <select name="month" class="date-select">
    <?php
        echo '<option value="'.$chosenMonth.'" selected>'.$chosenMonth.'</option>';
        for($i = 1; $i<12; $i++){
            echo '<option value="'.$i.'">'.$i.'</option>';
        }
    ?>
    </select>
    <select name="day" class="date-select">
    <?php
        echo '<option value="'.$chosenDay.'" selected>'.$chosenDay.'</option>';
        for($i = 1; $i<=$days_in_month; $i++){
            echo '<option value="'.$i.'">'.$i.'</option>';
        }
    ?>
    </select>
    <input type="submit" name="submit" id="activitysubmit" value="submit" />
    </form>
    </div>

    <p>Please select a date and press submit. You will be presented with a<br /> graph of player activity. Hover over a bar to view the players online at<br /> that time.</p><br /><br />


    <?php
    $chosenDate  =$chosenYear.'-'.$chosenMonth.'-'.$chosenDay;

    $get = $dbh->prepare("SELECT * FROM dcpmc_players_online WHERE date=?");
    $get->bindParam(1, $chosenDate, PDO::PARAM_STR);
    $get->execute();
    $result = $get->fetchAll();
    if(count($result) > 0 ){


        $left = 0;
        echo '<div class="chartWrapper">';
        echo '<p>Players online today</p>';
        echo '<div class="sidelegend"><p>Player count</p></div>';
        echo '<div class="bottomlegend">
        <div class="time"><p>0</p></div>    
        <div class="time"><p>1</p></div>    
        <div class="time"><p>2</p></div>    
        <div class="time"><p>3</p></div>    
        <div class="time"><p>4</p></div>    
        <div class="time"><p>5</p></div>    
        <div class="time"><p>6</p></div>    
        <div class="time"><p>7</p></div>    
        <div class="time"><p>8</p></div>    
        <div class="time"><p>9</p></div>    
        <div class="time"><p>10</p></div>   
        <div class="time"><p>11</p></div>   
        <div class="time"><p>12</p></div>   
        <div class="time"><p>13</p></div>   
        <div class="time"><p>14</p></div>   
        <div class="time"><p>15</p></div>   
        <div class="time"><p>16</p></div>   
        <div class="time"><p>17</p></div>   
        <div class="time"><p>18</p></div>   
        <div class="time"><p>19</p></div>   
        <div class="time"><p>20</p></div>   
        <div class="time"><p>21</p></div>   
        <div class="time"><p>22</p></div>   
        <div class="time"><p>23</p></div>   
        <div class="time"><p>24</p></div>   
        </div>';
        echo '<div class="bottomlegend2"><p>Time in GMT</p></div>';
        // loop through every hour of today
        for($h = 0; $h<=$hours; $h++){

            // add a zero in front of the first 9 hours
            if($h < 10){$h='0'.$h;}

            // loop through every minute of this hour
            for($m = 0; $m<=$minutes; $m++){

                // add a zero in front of the first 9 minutes
                if($m == 0){$m = '0'.$m;}

                if($m == 00 || $m == 15 || $m == 30 || $m == 45){
                    // build current time to check for players
                    $thisTime = $h.':'.$m.':00';

                    // get players online at this time in this hour of chosen date
                    $get = $dbh->prepare("SELECT * FROM dcpmc_players_online WHERE time=? AND date=?");
                    $get->bindParam(1, $thisTime, PDO::PARAM_STR);
                    $get->bindParam(2, $chosenDate, PDO::PARAM_STR);
                    $get->execute();
                    $now = $get->fetchAll();
                        if(count($now) > 0){
                            foreach($now AS $index){
                            $hoverDate = $index['time'];
                            $playerExplode = explode(",", $index['players']);
                            if(count($playerExplode == 1)){
                                foreach($playerExplode AS $index){
                                    if($index == 'none'){
                                        $playerCount = 0;
                                    }else{
                                        $playerCount = count($playerExplode);
                                    }
                                }
                            }

                            $left = $left+5;
                            $barHeight = $playerCount * 8; // 200px high container / 50 players = 8px per 1 player
                            echo '<div class="barContainer"><div class="bar1" style="height:'.$barHeight.'px;left:'.$left.'px;"></div>';

                            echo '<div class="hoverInfo"><p>'.$hoverDate.'</p><br />';
                            if($playerCount > 0){
                                echo '<p>'.$playerCount.' players online</p><br />';
                                foreach($playerExplode AS $index){
                                    echo '<p>'.$index.' </p>';
                                }
                            }else{
                                echo '<p>No players online.</p>';
                            }


                            echo '</div>';
                            echo '</div>';
                            }

                        }

正如您所看到的,我正在使用for循环来迭代每小时的每一分钟,我假设这会造成长时间的延迟。

Database表的结构如下所示:

enter image description here

1 个答案:

答案 0 :(得分:2)

您可以执行一些操作,即在SELECT中替换*仅包含对查看者重要的字段。

您还可以构建数据库条目,以便在播放器登录时写入“条目记录”,并在注销时写入“退出记录”。这样,你每个会话只获得两个记录,而不是每个在线玩家每分钟1个。然后,您可以调整SELECT以计算该人是否具有该日的条目记录,并仅返回“是”值。同样,您可以让PHP找到会话条目并退出记录并显示该会话的各种信息。

如果你想确定他们已经开启并且没有断开连接,那么你也可以像现在一样每分钟进行一次检查,如果他们不在服务器上,但他们的最后一个条目是登录,那么输入注销记录,因为它们可能已断开连接并且未创建记录。

我还建议添加分配给每个条目和退出的会话ID,以使所有计算更容易。