1

マルチテナントSaaSシステムの大きなテーブルのパフォーマンスを改善して、レポートをより高速にしようとしています。クラスタ化インデックスに列を追加すると、システムで挿入操作を行う時間が〜30msから1500〜2500msに増加しました!! この状況でこのテーブルに適用するのに最適なクラスター化インデックスオプションと非クラスター化インデックスは何ですか。

  • データベース:SQL Azure
  • このテーブルに対してINSERTとSELECTを実行するだけで、データは更新されません(UPDATE)
  • 同時INSERTの高負荷(キューからデータを消費する異なるワーカーとスレッド)
  • 100.000行/日(成長中)
  • 実際には600万行(成長中)
  • 各テナントは自分のIDのデータのみを読み取ります
  • 1テナントには10​​0〜3000のDeviceIdがあります

テーブル構造:
-TenantID(bigint)(smallintを使用できますが、将来Azureフェデレーションを使用する必要がある場合はbigintに変更しました)-DeviceID
(int)
-ReadID(bigint)(Identity)
-UIDRead(GUID)
-ReadDate (日時)
-SensorState1(tinyint)
-SensorState2(tinyint)
-SensorState3(tinyint)
...-
SensorState10(tinyint)

データの読み取りに使用される一般的なWHERE:
-WHERE DeviceId = @X and ReadDate Between @XDate and @YDate
-WHERE DeviceId IN(X、Y、Z)AND ReadDate Between @XDate and @YDate
-WHERE TenantId = @Y and ReadDate @XDateと@YDate
の間-WHERETenantId= @X AND DeviceID IN(X、Y、Z)AND ReadDate Between @XDate and @YDate
-WHERE TenantId = @X AND DeviceID = @ Y AND ReadDate Between @XDate and @YDate

4

1 に答える 1

1

主キーは何ですか?ReadDateTenantId、およびDeviceIdが一意の識別子を構成していると思いますか? その場合は、テーブル定義で主キーを宣言することにより、それらをこの順序でクラスター化します。範囲が連続するため、時系列データの場合は常にクラスター化インデックスの先頭に日付を配置します。(はい、各テナントが自分のデータのみを読み取ることは理解しています。サーバーはそれを認識しておらず、キャッシュはすべてのテナントのすべてのデータを保持する傾向があります。これは、ほとんどのテナントがほとんど同じ日付に関心があるためです。 )

可能な限り幅の狭い列を使用してください。BIGINT後でフェデレートする場合に備えて、今は使用しないでください。その日が来るなら、ALTER TABLEいつでもあなたを待っています。smalldatetime数秒必要でない限り使用してください。ReadId自然キーが既にあり、スペースを浪費し、リソース競合の原因となるため、ドロップします。通常の整数に変更UIDReadして、読者が 20 億人を超える日が来ることを願っています。

結果のテーブルが依然として挿入を受け入れるのが遅い場合、それはテーブルのせいではありません。サーバーを参照してください。

于 2013-03-14T02:03:01.637 に答える