2014-12-17 3 views
0

을 개선 나는 내가 최적화하고자하는 다음 쿼리가 :복잡한 쿼리 최적화 속도

SELECT 
    *, @rownum := @rownum + 1 AS rank 
FROM (
     SELECT 
       SUM(a.id = 1) as KILLS, 
       SUM(a.id = 2) as DEATHS, 
       SUM(a.id = 3) as WINS, 
       tb1.totalPlaytime, 
       p.playerName 

     FROM 
     (
       SELECT 
         player_id, 
         SUM(pg.timeEnded - pg.timeStarted) as totalPlaytime 
       FROM playergame pg 
       INNER JOIN player p 
         ON pg.player_id = p.id 
       WHERE pg.game_id IN(1, 2, 3) 
       GROUP BY 
         p.id 
       ORDER BY 
         p.playerName ASC 
     ) tb1 
     INNER JOIN playeraction pa 
       ON pa.player_id = tb1.player_id 
     INNER JOIN action a 
       ON pa.action_id = a.id 
     INNER JOIN player p 
       ON pa.player_id = p.id  
     GROUP BY 
       p.id 
     ORDER BY 
      KILLS DESC) tb2 
WHERE tb2.playerName LIKE "%" 

은 어떻게 든 내가이 MySQL의에 적합하지 있다는 느낌을 데있다. 좋은 통계적 접근을 위해 여러 테이블에서 많은 조치를 취하지 만 모든 것이 느려집니다. (? 아마도 빅 데이터)

이 내가 일을 시도

이제

Model

모델 않습니다 : 나는를 결합

결합 뷰에 조인 많은 JOINS가 VIEW에 들어갑니다. 이것은 나에게 개선을주지 않았다.

색인 테이블

내가이 속도를했다하지만 난 0.613s 아래의 전체 결과 집합을 얻을 관리 할 수 ​​있으며, 자주 사용하는 키를 색인.

:

작업 테이블에서 시작하고 사용 왼쪽

나에게 약간 다른 접근 방식을 주었다 조인하지만 아직 속도가 느린 것을 계속 조인

인덱스 (첫 번째 예는 여전히 가장 빠른)

indexes

는 어떤 힌트, 팁, 추가는, 개선은 환영

+0

글쎄, 얼마나 많은 레코드를 다루고 있습니까? 10kajillion 기록 데이터베이스를 통과하는 데 0.613 초가 매우 인상적입니다. 하나의 레코드를 스캔하는 데 0.613 초가 걸리는 것은 매우 불쌍한 것입니다. –

+0

인덱스를 사용하지 못하는 부분을 볼 수 있도록'EXPLAIN' 출력을 게시하십시오. – Barmar

+0

죄송합니다, 나는 그걸 잊어 버렸습니다. 약 146000 개의 레코드가 있습니다. 빠르게 증가해야합니다. –

답변

1

이전의 대답이 잘못되어 도움이되지 않았으므로 여기에 자신의 의견이있는 의견을 요약하여 요약 해 드리겠습니다.

쿼리 속도를 높이는 방법은 여러 가지가 있습니다.

  1. 중복 쿼리를 수행하지 않았는지 확인하십시오.
  2. 최대한 적은 수의 조인을 수행하십시오.
  3. 가능한 경우 여러 열에 대해 색인을 만듭니다.

  4. 이 내부 쿼리에서 INNER JOIN를 제거

    1. 이 내부 쿼리에서 ORDER BY를 제거 :

    2. 만들기 인덱스는 사용자가 질문에 쓴 쿼리에 대해서는 http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html

    /수 필요한 클러스터 된 경우 및 바꾸기 GROUP BY p.idGROUP BY player_id

  5. 색인이 의미있는 부분과 그렇지 않은 부분이 거의 없습니다.

    gameid에 대한 색인을 playergame에 작성하는 것이 적절하지 않을 수 있으므로 많은 행이 반환 될 수 있습니다. 이것이 가장 내적 인 쿼리에 대해 할 수있는 모든 것입니다.

    조인은 테이블에서 기대하는 것, 즉 직면 할 수있는 데이터의 양을 알고있는 경우 조금 최적화 할 수도 있습니다. 당신은 FPS의 MMO 게임 뒤에 데이터베이스를 구축하고 있는가하는 질문으로 생각할 수 있습니다. MMO는 게임 당 수백만 명의 사용자를 보유하게 될 것이며, FPS는 소수의 사용자 만 보유하게됩니다. 또한 게임의 종류에 따라 행동이 다를 수 있습니다. 이는 색인을보다 정확하게 작성하여 조회를 최적화하려고 시도 할 수 있음을의 L합니다. action의 내부 조인에서 정의 할 수있는 경우 gameid IN (...) 튜플에 인덱스를 만들면 (gameid, id)이 도움이 될 수 있습니다.

    와일드 카드 WHERE 절. playername에 색인을 만들려고 할 수도 있지만 검색 문자열 끝에 와일드 카드를 사용하는 경우 처음에는 별개의 색인이 필요하고 검색어 최적화 도구는 당신이 질의를 할 때마다 그들 사이를 전환하십시오.

    인덱스가 많을수록 삽입 및 삭제 속도가 느려지므로 최대한 자주 사용하십시오.

  6. 또 다른 것은 구조를 약간 재 설계 할 것입니다. 여전히 데이터베이스를 정규화 된 상태로 유지할 수는 있지만 일부 게임을 요약 한 테이블을 갖는 것이 유용 할 수 있습니다. 어제 이전에 발생한 게임에 대한 요약이있는 테이블이있을 수 있으며, 쿼리는 오늘의 데이터 만 요약 한 다음 필요에 따라 두 테이블을 조인합니다. 그런 다음 시간 소인을 작성하고 색인을 생성하거나 매일 테이블을 파티션하여 최적화 할 수 있습니다. 모든 것은 당신이 기대하는 하중에 달려 있습니다.

주제가 상당히 깊기 때문에 모든 것이 데이터의 뒤에 나오는 이야기에 달려 있습니다.