1

高速テキスト検索テーブルを備えた 700,000 エントリのデータベースがあります。各行には、時刻が関連付けられています。一度に 100 行のレコードを効率的にページングする必要があります。私は一日の終わりを追跡することによってこれを行っています。

実行に時間がかかりすぎています (15 秒)

クエリの例を次に示します。

SELECT * 
FROM Objects o, FTSObjects f
WHERE f.rowid = o.AutoIncID AND 
  o.TimeStamp > '2012-07-11 14:24:16.582' AND 
  o.TimeStamp <= '2012-07-12 04:00:00.000' AND 
  o.Name='GPSHistory' 
ORDER BY o.TimeStamp 
LIMIT 100

タイムスタンプ フィールドにはインデックスが付けられます。

これは、Order Byステートメントが返されたすべてのレコードをソートしてから制限を行っているためだと思いますが、よくわかりません。

提案?

4

2 に答える 2

2

はい、ORDER BYは の前に処理されますLIMITが、それは正しい機能です。そうしないと、ページングは​​実際には機能しません。しかし、最適化のためのいくつかのアイデア。

  1. SELECT *絶対に必要でない場合はしないでください。結果をページングしている場合、ユーザーが見ている両方のテーブルのすべてのフィールドではないことはほぼ確実だからです。
  2. 対象のインデックスを作成してAutoIncID, TimeStamp、データ ページを読み取らないようにします。Nameから来ている場合は、そのインデックスに追加しObjectsます。
  3. から来ている場合rowid, Name、カバーされたインデックスを に作成します。NameFTSObjects
  4. 返されるフィールドを制限できる場合は、対象となるインデックスにそれらのフィールドを追加することを検討してください。書き込み時間に影響するため、インデックスが大きくなりすぎないようにします。
于 2013-07-11T20:17:00.883 に答える
2

最善の方法は、優れた DBA に生成された計画を見てもらい、それが最適な計画であることを確認することです (たとえば、計画にテーブル スキャンがないことを確認します。これは、オプティマイザが不適切な統計を使用した場合に発生する可能性があります)。

役立つ可能性のあるいくつかの事項を次に示します。

  • にインデックスを追加します。Objects.Name場合によっては、 と に複合インデックスを追加NameしますTimeStamp
  • rowidまだ存在しFTSObjectsないインデックスを追加します
  • UPDATE STATISTICSインデックスで定期的に (理想的には大規模な更新の後、Timestampまたは更新が継続している場合は毎日)
  • クラスター化インデックスを再構築します (ある場合)。これは、クラスター化インデックスがシーケンシャル挿入を取得しないフィールド (たとえば、挿入がランダムな場所にある char フィールド) にある場合に役立ちます。
  • 必要がないselect *場合はしないでください - I/O 時間が増加します

文字列を にキャストすることもできますDATETIMEが、SQL はデータを文字列にキャストするのに対して暗黙的にこれを行うと思います (datetime でインデックスを使用しません)。

SELECT * 
FROM Objects o, FTSObjects f
WHERE f.rowid = o.AutoIncID AND 
  o.TimeStamp > CONVERT(DATETIME,'2012-07-11 14:24:16.582') AND 
  o.TimeStamp <= CONVERT(DATETIME,'2012-07-12 04:00:00.000') AND 
  o.Name='GPSHistory' 
ORDER BY o.TimeStamp 
LIMIT 100
于 2013-07-11T21:29:13.090 に答える