2012-07-03 4 views
1

저는 지금까지 이름, ID, 점수 및 순위가 포함 된 7000 개 이상의 리더 보드 데이터가있는 프로젝트를 진행하고 있습니다. 계속 확장되고 있으며, 누군가가 새로운 점수를 올릴 때마다 모든 것을 업데이트하려고 시도한 후에 서버가 시간 초과되는 걸림돌을 때리고 있습니다.mySQL을 사용하여 1000 개의 행을 업데이트하는 가장 효율적인 방법은 무엇입니까?

현재 루프 된 execute() 호출과 결합 된 쿼리와 함께 PDO를 사용하고 있습니다. 이 방법을 사용하는 것이 훨씬 빠릅니다 (아마도 단일 MySQL 쿼리에서)? 또는 리더 보드 업데이트를 처리하는 방법에 대한 제안 사항이 있습니까? 이하지로 밝혀 그래서 만약

$stmt = $dbh->prepare("SELECT * FROM high_scores ORDER BY score DESC"); 
    $stmt->execute(); 

    $stmt->setFetchMode(PDO::FETCH_ASSOC); 
    $results = $stmt->fetchAll(); 

    // 

    $numItems = count($results); 

    // is this OK or a no-no? 

    try { 

     $stmt = $dbh->prepare("UPDATE high_scores SET rank = :rank WHERE uid = :uid"); 

     for($i=0; $i<$numItems; $i++){ 
      $rank = $i + 1; 
      $uid = $results[$i]['uid']; 
      $stmt->execute(array(':rank' => $rank, ':uid' => $uid)); 
     } 

     return true; 

    } catch (PDOException $e) { 
     echo($e->getMessage()); 
    } 

답변

1

왜 순위를 저장해야합니까? 그건 비정규 화 형식입니다. 정말로 필요 했습니까? 아니면 필요할 것으로 예상 되었기 때문에이 단계를 구현 했습니까?

http://thinkdiff.net/mysql/how-to-get-rank-using-mysql-query/

어쩌면이 수행하는 방법을 시도 :

예를 들어이 솔루션을 참조하십시오?

또한 그가 만든 예제를 보면 쿼리에서 변수를 사용할 수 있습니다. 그러면이 업데이트 문을 단일 쿼리로 결합 할 수 있습니다. 루프 내의 쿼리는 어려운 쿼리이며 불행히도 실제로는 효율적이지 않습니다.

+0

이것은 큰 도움이되었습니다. 감사합니다. – maskedbacon

0

나는, 당신은 하나 개의 쿼리와 나는 불행하게도,이 시도 할 바로 사용할 수 MySQL이없는

UPDATE high_scores a SET rank = (SELECT count(uid) + 1 FROM high_scores b WHERE b.score > a.score) ORDER BY score DESC 

같은 것을이 모든 것을 할 수 있다고 생각 가능하다면 나는 이것을 지울 것이다.

0

mysql의 '사례'에 대한 빠른 google을 사용해보십시오.

하지만 당신은 대부분 여기에 대한 답을 찾을 수 있습니다 : Stackoverflow #9346755

는 기본적으로, 당신이 자신의 "내부 스위치 문"이다가 하나 개의 SQL 라인을 가지고있다. 특정 필드에 특정 값이있을 때 수행 할 작업을 지정해야합니다. EG. 위 링크에서 말하고있는 것입니다 ...

When `id` is 1, then set the value to 12. 
When `id` is 2, then set the value to 42. 
etc. 

유일한 걱정은 7000+ 행 일 수 있습니다.

그러나 PHP를 사용하면 배열에 데이터가 있고 array_slice()를 사용하여 한 번에 200/300 개의 레코드를 가져 와서 SQL 행을 설정하고 실행합니다. 그런 다음 PHP 배열의 끝에 도달 할 때까지 다음 200/300 레코드를 가져 와서 반복하십시오.

편집 : 위의 내용은 키와 같은 다른 필드를 기반으로 한 필드를 업데이트하는 경우에만 작동합니다.

관련 문제