2

ここにテーブルがあります:

CREATE TABLE Meetings
(
  ID int PRIMRY KEY IDENTITY(1,1)
  StartDate DateTime NOT NULL,
  EndDate DateTime NULL,
  Field1 varchar(50),
  Field2 varchar(50),
  Field3 varchar(50),
  Field4 varchar(50)
)

数千行あります。データ範囲は、さまざまなサイズ (数日から 50 年まで) にすることができます。

クエリは次のとおりです。

DECLARE @ApplicableDate DateTime

SELECT ID, StartDate, EndDate, Field1, Field2, Field3, Field4
FROM Meetings
WHERE StartDate <= @ApplicableDate AND
  (EndDate is null || @ApplicableDate <= EndDate)

日付範囲が大きくなる可能性があるため、テーブルの大部分 (行の 20% ~ 50%) が返される可能性があります。

クエリは必要な行を単純な方法で表していますが、パフォーマンスはかなり悪いです。追加するインデックスに関係なく、クラスター化されたインデックス スキャンを実行します。私はもう試した:

  • 開始日
  • 開始日、終了日

このクエリのパフォーマンスを改善するにはどうすればよいですか?


この質問この質問の回答も確認しました。これらのソリューションは私の状況では役に立ちません - 日付の別のテーブルを作成してクエリを等価クエリに変えることで、ビジネスのデータをいじりたくありません (終了日が変更された場合、または null の場合はどうなりますか? )、またはデータをモーフィングして空間インデックスに適合させます。

それでも、私はデータ構造の変更の可能性を受け入れています (特に、行を追加せず、奇妙なデータ型を使用しない場合)。

4

2 に答える 2

3

私の構文では、SQL Server を使用していると想定しています。

ID の主キーを非クラスター化インデックスにします。

ID int PRIMARY KEY NONCLUSTERED IDENTITY(1,1),

StartDate 列にクラスター化インデックスを作成します。

CREATE CLUSTERED INDEX ix_Meetings_StartDate
ON Meetings (StartDate)

クエリをそのまま試してください。クラスター化された PK の場合と同様にデータが保存される可能性がありますが、クエリ エンジンは、データが開始日によってクラスター化されていることを事前に認識します。

于 2010-08-06T21:45:32.833 に答える
2

クエリが 20% から 50% のレコードを返す場合、スキャンが最適なオプションであることがよくあります。インデックスがある場合は、常にインデックス内のデータを検索する必要があり、テーブル内のレコード アドレスが含まれています。次に、このレコードを含むページをディスクから取得する必要があり、インデックス内の隣接するレコードが分散する危険があります。ディスク全体。

本当に多くのレコードが必要で、パフォーマンスが悪い場合は、次のことを確認してください。

  • ディスク速度が問題ですか?
  • ネットワーク帯域幅ですか?
  • RAM/キャッシュに制限がありますか?
于 2010-08-06T21:25:22.633 に答える