0

私はこのクエリを持っています:

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 の使用が許可されない理由がわかりません。このクエリをもっと速くする必要があります。何か助けはありますか?

4

1 に答える 1

0
  • 指定されたインデックスは ([TelemetryId],[TimestampTicks]) であり、([TimestampTicks]) ではなく、[TelemetryId] にはフィルター条件がありません。
  • テスト DB に完全な作業データ ボリュームがない場合、テストの実行計画は本番環境の実行計画を反映していない可能性があります。
  • DB エンジンは、インデックスの使用を選択する前に、インデックスの使用がテーブル スキャンよりも効率的かどうかをモデル化しようとします。多くの場合、予想されるデータ量がテーブルの ~10% を超える場合、有用に見えるインデックスが無視されることがあります。(ただし、この場合はありそうにありません。)
  • 架空のパフォーマンスの問題を追跡することは、非常に時間の無駄です。この場合、実際のパフォーマンスの問題はありますか?
于 2013-03-07T18:27:47.673 に答える