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

标签 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循环遍历每小时的每一分钟,我假设这导致了长时间的延迟。

数据库表的结构如下所示:

enter image description here

最佳答案

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

您还可以构建数据库条目,以便在玩家登录时写入“进入记录”,在玩家注销时写入“退出记录”。这样,您每次 session 只需获取两条记录,而不是每个在线玩家每分钟获取 1 条记录。然后,您可以调整 SELECT 来计算此人当天是否有条目记录,并仅返回"is"值。同样,您可以让 PHP 查找 session 进入和退出记录并显示该 session 的各种信息。

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

我还建议添加分配给每个入口和导出的 session ID,以使所有计算更容易。

关于php - 如何提高MySql数据库处理数据的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21581310/

相关文章:

PHP - 行计数多次显示相同数字的问题,我该如何解决这个问题?

php - 使用 mysql php 自动更新图像,我假设 javascript

mysql - 使用 JSON 中的 Feeds 模块导入时,13 位数字会得到指数格式

performance - 避免使用 OpenGL 顶点数组在屏幕外绘制

php - 加载 Magento 页面时出现奇怪的错误

php - 构建比较字符串相似度的推荐系统

php - 循环/迭代AWS PHP SDK响应

php - 如何使用php将mysql结果连接成一个字符串

objective-c - Objective C 消息分发机制

Android View 动画 - 在大屏幕上表现不佳