2016-07-29 3 views
2

1 천만 개가 넘는 행이있는 테이블에서 쿼리를 실행해야합니다. 테이블 구조는여러 열에 대한 인덱싱

user(varchar 100), 
played(int 11), 
won(int 11), 
lost(int 11), 
drawn(int 11), 
user1(varchar 30), 
user2(varchar 30). 


Where 
User - primary key 
user1 - index 
user2 - index 

MySQL 데이터베이스 엔진의 MyISAM이다.

내 문제는 - 아래 쿼리를 실행하면 17 초가 넘습니다.

SELECT * FROM h2hstats 
WHERE (won+lost+drawn) > 5 
    AND (user1 = '717054941' OR user2 = '717054941') 

어떻게이 실행 시간을 줄일 수 있습니까?

(won + lost + drawn) 열에 다른 색인을 생성합니까?

+0

아니를, 당신이 그들을 위해 검색하지 않기 때문에. 조건이 충족되면 데이터에 액세스 할 수 있습니다. 따라서 user1 및 user2의 적절한 색인 생성에 따라 다릅니다. 숫자 값만 포함하는 열에 숫자 필드 유형 (INTEGER 또는 BIGINT)을 사용하면 성능에 도움이됩니다. – syck

+1

이 방법으로 작업 한 적이 없지만 어쩌면 다음과 같을 수도 있습니다. AND 717054941 IN (user1, user2) – Jeff

+0

win + last + drawn에서 계산 된 인덱스를 만드는 것이 좋습니다 .http : //dev.mysql.com/doc/refman/5.7 /en/generated-column-index-optimizations.html.. 또한 두 개의 별도 색인 (user1, user2)을 어떻게 사용할 수 있는지 잘 모르겠다. – TheGameiswar

답변

2

먼저 사용자 열이 숫자 인 경우 상수에 작은 따옴표를 사용하지 마십시오. 이로 인해 최적화 프로그램을 혼동 할 수 있습니다. 이것은 아마 귀하의 쿼리 (내 SQL은 OR에 대한 인덱스를 사용하는 가난한 일을) 도움이되지 않습니다,하지만 노력 가치가 있습니다.

다음과 같이 쿼리를 다시 작성 :

SELECT * 
FROM h2hstats 
WHERE (won + lost + drawn) > 5 AND user1 = 717054941 
UNION ALL 
SELECT * 
FROM h2hstats 
WHERE (won + lost + drawn) > 5 AND user2 = 717054941 ; 

MySQL이 확실히 하위 쿼리의 각 인덱스를 사용합니다. 성능이 향상됩니다.

(참고 :.이 버전은이 가능한 경우, 당신은 UNION ALL보다는 UNION을 사용할 수 있습니다 <>user2user1 있다고 가정합니다.)

관련 문제