2013-03-07 2 views
0

나는이 쿼리가 :Sqlite가이 ORDER BY에 대한 색인을 사용하지 않는 이유는 무엇입니까?

SELECT * FROM Events e 
    INNER JOIN Telemetry ss ON ss.Id = e.TelemetryId 
    INNER JOIN Services s ON s.Id = ss.ServiceId 
    WHERE s.AssetId = @AssetId AND e.TimestampTicks >= @StartTime 
    ORDER BY e.TimestampTicks LIMIT 1000 

을 나는이 인덱스가 :

CREATE INDEX [IX_Events_TelemetryId_TimestampTicks] ON [Events] ([TelemetryId],[TimestampTicks]) 

그러나 인덱스가 ORDER BY 절에 사용되지 않습니다. 나는이 질의 설명을 얻는다 :

0|0|2|SCAN TABLE Services AS s (~44 rows) 
0|1|1|SEARCH TABLE Telemetry AS ss USING AUTOMATIC COVERING INDEX (ServiceId=?) (~5 rows) 
0|2|0|SEARCH TABLE Events AS e USING INDEX IX_Events_TelemetryId_TimestampTicks (TelemetryId=? AND TimestampTicks>?) (~1816 rows) 
0|0|0|USE TEMP B-TREE FOR ORDER BY 

왜 B-TREE인가? 인덱스를 뒤집 으면 실제로 성능이 떨어집니다. 그 쿼리 계획은 다음과 같습니다.

0|0|0|SEARCH TABLE Events AS e USING INDEX IX_Events_TimestampTicks_TelemetryId (TimestampTicks>?) (~4031303 rows) 
0|1|1|SEARCH TABLE Telemetry AS ss USING INTEGER PRIMARY KEY (rowid=?) (~1 rows) 
0|2|2|SEARCH TABLE Services AS s USING INTEGER PRIMARY KEY (rowid=?) (~1 rows) 

왜 이러한 순서로 TelemetryId를 사용할 수 없는지 모르겠습니다. 정말이 쿼리가 더 빨리 필요합니다. 어떤 도움이 필요합니까?

+0

두 번째 쿼리 계획이 빠릅니다. 얼마나 더 나쁜 성능을 측정 했습니까? –

+0

처음에는 약 1 초가 걸리고 두 번째 시간에는 약 3 초가 걸립니다. – Brannon

답변

0
  • 지정한 색인은 [TelemetryId], [TimestampTicks]가 아니고 [TimestampTicks]가 아니며 [TelemetryId]에 대한 기준이 없습니다.
  • 테스트 DB에 데이터가 가득 차 있지 않은 경우 테스트의 실행 계획에 프로덕션의 실행 계획이 반영되지 않을 수 있습니다.
  • DB 엔진은 인덱스 사용을 선택하기 전에 테이블 검색보다 whither 인덱스 사용을 더 효율적으로 모델링하려고합니다. 종종 예상되는 데이터 볼륨이 테이블의 10 % 이상인 경우 유용한 인덱스가 무시 될 수 있습니다. (비록이 경우에는 그럴 가능성이 없습니다.)
  • 가상 성능 문제를 추적하는 것은 훌륭한 시간 낭비입니다. 이 인스턴스에 실제 성능 문제가 있습니까?
+0

TelemetryId에는 필터 기준이 있습니다. JOIN에 있는데, Sqlite에서 WHERE가 번역 된 것으로 이해합니다. – Brannon

+0

@Brannon : 나는이 진술을 통해 인덱스가 사용되었다는 것을 분명히 알 수 있다고 생각합니다. "인덱스를 역전하면 실제로 성능이 떨어집니다". –

+0

구문 "USE TEMP B-TREE"는 ORDER BY 절에 대한 인덱스를 사용하지 않는다는 의미입니다. – Brannon