почему 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. Мне действительно нужен этот запрос быстрее. Любая помощь?


person Brannon    schedule 07.03.2013    source источник
comment
Второй план запроса выглядит быстрее. Насколько хуже производительность вы измерили?   -  person CL.    schedule 07.03.2013
comment
Первая занимает около одной секунды, а второй - около трех.   -  person Brannon    schedule 08.03.2013


Ответы (1)


  • Указанный индекс находится на ([TelemetryId], [TimestampTicks]), а не на ([TimestampTicks]), и для [TelemetryId] нет критериев фильтрации.
  • Если тестовая БД не имеет полного объема рабочих данных, планы выполнения в тесте могут не отражать планы выполнения в производственной среде.
  • Механизмы БД пытаются смоделировать, какое использование индекса более эффективно, чем сканирование таблицы, прежде чем выбрать использование индекса. Часто полезный индекс может игнорироваться, если ожидаемый объем данных> ~ 10% таблицы. (Хотя в данном случае это маловероятно.)
  • Преследование воображаемых проблем с производительностью - огромная трата времени. Есть ли в этом случае реальная проблема с производительностью?
person Pieter Geerkens    schedule 07.03.2013
comment
На TelemetryId есть критерии фильтрации. Это в JOIN, который, как я понимаю, переводится как WHERE в Sqlite land. - person Brannon; 08.03.2013
comment
@Brannon: Я думаю, это утверждение проясняет, что индекс используется, но не совсем то, как и где вы думаете: если я переверну индекс, у меня действительно ухудшится производительность. - person Pieter Geerkens; 08.03.2013
comment
Фраза USE TEMP B-TREE означает, что он не использует индекс для предложения ORDER BY. - person Brannon; 06.04.2013