2012-12-27 3 views
2

이벤트 테이블에 약 100,000 개의 행이 있습니다. 그 ...SQLite 쿼리 개선

SELECT id FROM event 
NATURAL JOIN (
    SELECT subj_id, max(timestamp) AS timestamp 
    FROM event WHERE (
     timestamp >= 1342052128597 AND timestamp <= 9223372036854775807 
     AND NOT subj_interpretation = 46)) 
    GROUP BY subj_id) 
GROUP BY subj_id 
ORDER BY 
timestamp DESC 

을에 "이벤트"테이블에 복잡한 쿼리 다음이 쿼리를 최적화하는 방법에 대한 의견을하고 싶은 쿼리는 0.06-0.07 초에 여기 수행한다. 어떤 아이디어가 좋은 질의 및/또는 쿼리의 재구성이 될 것입니다.

CREATE INDEX event_subj_id ON event(subj_id, timestamp, subj_interpretation) 

을 다음과 같이 쿼리 계획 같습니다 :

현재 내가 사용하고

1 0 0 SCAN TABLE event USING COVERING INDEX event_subj_id (~27777 rows) 
0 0 1 SCAN SUBQUERY 1 (~100 rows) 
0 1 0 SEARCH TABLE event USING INDEX event_subj_id (subj_id=? AND timestamp=?) (~9 rows) 
0 0 0 USE TEMP B-TREE FOR GROUP BY 
0 0 0 USE TEMP B-TREE FOR ORDER BY 
+3

': 당신이 그것을에 id 열을 추가하는 경우 그러나, SQLite는 실제로 성능을 두 배로 수있는 events 테이블 자체의 모든 기록을 찾아 볼 필요가 제거 커버링 인덱스로 사용할 수 있습니다 100K 줄에서 0.06 초는 나에게 꽤 좋은 것처럼 들립니다. 실제 실적 기대치 또는 요구 사항은 무엇입니까? –

+0

0.03 또는 0.02 약간의 구조 조정만으로 성공할 수 있다고 확신합니다. – smor

+2

어, 당신은 쿼리 성능을 두 배로 또는 세 배로 높일 수 있습니다. 적절한 필드 지수와 같은 일반적인 용의자를 모두 확인 했습니까? –

답변

1

당신은 DISTINCT을 제거하여 두 번째 쿼리를 최적화 할 수 있습니다 GROUP BY subj_id 이미 보장하기 때문에,이 할 수 없음을 나타 중복 기록이 되십시오 :

SELECT id, 
     subj_id, 
     max(timestamp) AS timestamp 
FROM event 
WHERE timestamp BETWEEN 1342055894621 AND 9223372036854775807 
    AND subj_interpretation != 46 
GROUP BY subj_id 
ORDER BY timestamp 

색인 자체는 이미 GROUP BY/timestamp/subj_interpretation 조회에 최적입니다.

0 0 0 SCAN TABLE event USING COVERING INDEX event_subj_id_plus_id 
0 0 0 USE TEMP B-TREE FOR ORDER BY 
+0

멋지다. D : 많이 고마워. 또한 내 return에서 subj_id에 관심이 없기 때문에 그것을 그룹화하는 것만으로 훨씬 빨리 만들 수 있습니다. 그들을 사용하지 않고 각 subj_id의 max_timestamp를 사용하는 방법이 있습니까? – smor

+0

'max (timestamp)'를 어딘가에 사용해야합니다. 당신은'SELECT id + 0 * max (timestamp) ...'와 같은 것을 시도 할 수있다. 그러나 이것은 많은 차이를 만든다. –