2012-10-14 4 views
3

ORDER BY 문을 쿼리에 추가하면 쿼리가 매우 느려집니다.Sqlite ORDER BY 그룹의 수가 느립니다.

SELECT ClientIpAddress, Agentstring, Count(ClientIpAddress) AS Count FROM LogEntries 
WHERE SiteIisId = 3 AND DateTime >= '13-09-2012 00:00:00' 
GROUP BY ClientIpAddress, Agentstring 
LIMIT 5 

ET :

여기에 의해 ORDER없이 내 쿼리의 지금 1ms의

그리고 주문에 의해 :

SELECT ClientIpAddress, Agentstring, Count(ClientIpAddress) AS Count FROM LogEntries 
WHERE SiteIisId = 3 AND DateTime >= '13-09-2012 00:00:00' 
GROUP BY ClientIpAddress, Agentstring 
ORDER BY Count DESC 
LIMIT 5 

ET : 294 MS

나 '표 m 쿼리에는 1.380.855 개의 행이 포함됩니다.

CREATE INDEX "LogEntries_MostActiveClients" ON "LogEntries" ("ClientIpAddress" ASC, "Agentstring" ASC, "SiteIisId" ASC, "DateTime" DESC) 

EXPLAIN QUERY PLAN SQLite는 내 인덱스를 사용하여 테이블을 스캔 있어요하여 내 주문에 대한 TEMB B-TREE을 사용 하더군요 사용 :

여기 내가 사용 인덱스입니다.

이 문제를 어떻게 극복 할 수 있습니까? 분명히 Count의 색인을 생성 할 수 없으므로 어떻게해야합니까?

감사합니다.

+0

어떤 색인이 있습니까? –

+1

'DateTime '에 대한 비교는 가장 중요한 필드 인 연으로 시작하지 않기 때문에 올바르게 작동하지 않습니다. [지원되는 날짜 형식] (http://www.sqlite.org/lang_datefunc.html) 중 하나를 사용해야합니다. –

+0

죄송합니다. 사용중인 색인을 추가했습니다. DateTime 문제를 지적 해 주셔서 감사합니다. – jhovgaard

답변

1

결과 집합을 단계별로 실행할 때 SQLite는 가능한 한 많은 값을 으로 계산하려고합니다.

첫 번째 쿼리에서 SQLite는 테이블의 모든 주소/에이전트 값을 그룹화 할 필요가 없습니다. 최대한 빨리 색인을 통해 첫 번째 다섯 ClientIpAddress/Agentstring 조합의 기록을 읽었을 때 멈출 수 있습니다.

두 번째 쿼리에서는이 작업을 수행 할 수 없습니다. 모든 주소/에이전트 그룹을 정렬하기 전에 계산을 완료하고 처음 다섯 개를 선택해야합니다.

정렬 할 임시 결과의 레코드가 이미 캐시에 있고 원본 테이블의 데이터보다 작기 때문에 대부분의 시간은 정렬, 그룹화에 소비되지 않는다고 생각합니다.

정렬에 문제가있는 경우 가장 큰 5 개 계산의 예상 크기가있는 경우 HAVING "Count" >= some_limit 절을 추가하여 정렬 할 레코드 수를 줄일 수 있습니다.

그룹화를 피할 수있는 방법은 없습니다. 당신이 시도 할 수있는 것은 다음과 같은 일반적인 최적화 작은 개선 얻을 수 있습니다 :

  • 증가 SQLite는의 page cache 당신의 작업 집합의 크기를;
  • covering index을 만들면 테이블 자체에서 조회를 수행하지 않아도됩니다.

또 다른 방법은이 쿼리의 값을 사전 계산하는 것입니다. Count과 별도의 테이블을 만들고 로그 항목을 추가 할 때마다 업데이트하십시오. 이렇게하면 업데이트가 느려지므로 타임 스탬프에 사용할 세분화를 결정해야합니다.

+0

답변 해 주셔서 감사합니다. 불행히도'HAVING' 문을 추가하면 실행 시간에만 추가됩니다 (ORDER BY 포함 또는 제외). 내가이 문제를 어떻게 극복 할 수 있는지 제안 해 주시겠습니까? 이 접근 방식 일 필요는 없습니다. – jhovgaard

0

SQLite 합병으로 발견 된 응용 프로그램을 here으로 테스트하십시오.

리처드는 Hipp는 최근 발표 :

우리는 최근 SQLite는의 쿼리 최적화에 상당한 개선 사항을 만들었습니다. 특히, 최신 코드는 인덱스와 검색 명령을 신중하게 선택하여 모든 정렬 작업을 수행하지 않아도 ORDER BY 절을 만족할 수있는 시점을 인식 할 수있어 훨씬 더 나은 작업을 수행합니다 ( ). 이 최적화는 큰 결과 집합과 함께 쿼리에 대해 상당한 성능 향상을 가져올 수 있습니다.

전자 메일 스레드는 here입니다.

+0

이러한 향상된 기능은 결과가 이미 색인 또는 'GROUP BY'로 인해 주문 된 경우에만 해당됩니다. –

+0

예, 적절한 색인이 없으면 추가해야합니다. –