2014-02-05 5 views
0

매분 온라인 상태 인 사람을 기록하여 서버에서 플레이어 활동을 모니터링하고 있습니다. 플레이어 목록은 varchar 필드에 쉼표로 구분 된 단일 문자열로 저장됩니다.MySql 데이터베이스의 데이터 처리 속도를 향상시키는 방법

플레이어가 해당 날짜와 달에 누가 온라인 상태인지 표시 할 날짜를 선택하게했습니다.

스크립트는 잘 작동하고 내가하는 것처럼 데이터를 처리하는 데 오랜 시간이 걸린다는 점을 제외하고는 예상대로 수행됩니다. 현재 페이지가로드되는 데 약 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 루프를 사용하고 볼 수 있듯이.

데이터베이스 테이블의 구조는 다음과 같습니다 : 당신이 할 수있는 몇 가지, 즉 시청자에게 중요 필드 만 사용하여 SELECT에 * 대체가 있습니다

enter image description here

+0

날짜 필드에 인덱스를 설정 했습니까? – jeff

+0

아니요 기본 키를 사용자 ID로 설정했습니다 – crm

+2

이 쿼리를 60 번 이상 실행하면 다음과 같이 나타납니다 :'SELECT * FROM dcpmc_players_online where time =? AND 날짜 =? '. 대신 두 시간 범위에서 모든 행을 하나의 쿼리로 가져온 다음 수신 된 데이터를 반복 할 수 있습니다. – degenerate

답변

2

.

또한 플레이어가 로그온 할 때 '항목 레코드'를 쓰고 로그 오프 할 때 '끝내기 레코드'를 쓸 수 있습니다. 이렇게하면 플레이어 당 온라인 1 분당 1 회가 아닌 세션 당 2 개의 기록 만 잡을 수 있습니다. 그런 다음 SELECT를 조정하여 해당 날짜에 대한 항목 레코드가 있었는지 여부를 계산하고 '예'값만 반환 할 수 있습니다. 비슷하게 PHP가 세션 입력 및 종료 레코드를 찾고 해당 세션에 대한 모든 종류의 정보를 표시하도록 할 수 있습니다.

서버가 켜져 있고 연결이 끊어지지 않았 음을 확인하려면 매분 확인을 할 수 있으며 서버에 없지만 마지막 항목이 로그인 일 경우, 연결이 끊어져서 레코드가 작성되지 않았으므로 수동으로 로그 아웃 레코드를 입력하십시오.

또한 모든 계산을 더 쉽게하기 위해 각 입력 및 종료에 지정된 세션 ID를 추가하는 것이 좋습니다.

관련 문제