1

MS SQL 2008 を使用すると、すべてのテーブルに、挿入されたレコードの「I」、更新されたレコードの「U」、削除されたレコードの「D」を示す Status varchar(1) 列、および DateCreated 日時列と DateUpdated 日時列が含まれます。 .

ほとんどの場合、アクティブなレコードのみをテーブルにクエリしたいので、次のようにします。

SELECT column FROM table WHERE Status <> 'D'

使用状況を把握するために、これは最も頻繁に使用されるフィルターであり、ほぼすべてのクエリに表示され、テーブルが結合されるときに複数回表示されます。

パフォーマンスの最大化に重点を置いて、新しい Web アプリケーションとデータベースを開発しています。1 つの提案は、このプロジェクトと将来のプロジェクトから始めて、レコードが削除されたかどうかを示し、2 つの日時フィールドから更新されたステータスを推測するために、varchar(1) Status 列パターンを「IsDeleted」のようなものに置き換えることです。

言い換えると...

SELECT column as InsertedRecords FROM table WHERE Status = 'I' -- Rare case
SELECT column as UpdatedRecords FROM table WHERE Status = 'U' -- Rare case
SELECT column as ActiveRecords FROM table WHERE Status <> 'D'
SELECT column as DeletedRecords FROM table WHERE Status = 'D'

...代わりに次のようになります...

SELECT column as InsertedRecords FROM table WHERE IsDeleted = 0 AND DateCreated = DateUpdated -- Rare case
SELECT column as UpdatedRecords FROM table WHERE IsDeleted = 0 AND DateCreated <> DateUpdated -- Rare case
SELECT column as ActiveRecords FROM table WHERE IsDeleted = 0
SELECT column as DeletedRecords FROM table WHERE IsDeleted = 1

具体的なパフォーマンスの利点/影響 (主要なインデックスと大規模なクエリ) はありますか? または両方の実装が完全に受け入れられますか? 一貫性を保つために現在のパターンを継続して、以前に作成されたアプリケーション/データベースと整合させることに不利な点はありますか?

4

2 に答える 2

1

あまり詳しく説明しなくても (自分で調べることができます)、非選択的なデータよりもパフォーマンスを向上させる他の方法として、フィルター処理されたインデックスとテーブルのパーティショニングがあります。

たとえば、その中の特定のデータを探している場合はWHERE Status <> 'D'、フィルター処理されたインデックスが役立つ場合があります。基本的に、関心のあるレコードのみにインデックスを付け、インデックスを少し小さくします (そしておそらく高速にします)。

個人的には、ビット パターンよりも I/U/D パターンを好みます。これは「直交」であり、私が慣れ親しんでいるものです。

また、削除されたレコードをあまり見ない場合は、それらを別のパーティションに分割することをお勧めします。ユーザーには透過的です (テーブルは 1 つしか表示されません) が、実際にはバックグラウンドで低速で安価なディスクに配置したり、バックアップを減らしたりすることができます。 (削除された) パーティション。

また、めったに使用しないのであれば、これらの削除されたレコードがこのテーブルを乱雑にしている理由も検討します。おそらく、それらをデータ ウェアハウスに移動し、代わりにそこで報告することができます。

于 2013-10-04T01:52:28.930 に答える
1

char(1) 列の代わりにビット列を使用するだけで、失うことも得ることもあまりないと思います。

インデックス作成に関しては、ビット列だけのインデックスでは、1 と 0 の 2 つの値しかない可能性があるため、あまり価値がありません (列は null 可能ではないと仮定します)。

WHERE条件付きのクエリは、DateCreated <> DateUpdatedインデックスを効率的に使用できず、既存の char(1) フィールドよりも動作が悪い可能性が高いため、うまく機能しません。

全体として、既存のソリューションはビット フィールドと日付フィールドよりもうまく機能すると思います。数値を使用したい場合は、代わりに tinyint フィールドに値を格納できます (例: I = 0、U = 1、D = 2)。

パフォーマンスを向上させるためにできることは、さらに 2 つあります。

  • 実行するクエリに応じて、bit/char 列およびその他の列に基づいてインデックスを作成します (例:IsDeletedおよびDateCreated) 。
  • 返された列SELECTをインデックスに含めて、クエリがテーブルからレコードを検索する必要がないようにします。
于 2013-10-04T00:22:27.373 に答える