0

最終的な一貫性のために、クライアントとデータの同期に取り組んでいます。サーバーは、データベース ID と行バージョン/タイムスタンプのリストを公開します。クライアントは、間違ったバージョン番号のデータを要求します。データに一貫性がない主な理由は、ブローカー ノード間のネットワークの問題、スプリット ブレインなどです。

テーブルからデータを読み取るとき、主キーではない述語に基づいてデータを要求します。利用可能なリージョンを反復して、リージョンごとにデータを読み取ります。これは私の選択です:

SELECT DatabaseId, VersionTimestamp, OperationId
FROM TableX 
WHERE RegionId = 1

これにより、クエリごとにインデックス スキャンが行われるため、RegionId 列に非クラスター化インデックスがあり、そのインデックスに選択した列が含まれているかどうか疑問に思っています。

CREATE NONCLUSTERED INDEX [ID_TableX_RegionId_Sync]
ON [dbo].[TableX] ([RegionId])
INCLUDE ([DatabaseId],[VersionTimestamp],[OperationId])

VersionTimestampは行バージョン/タイムスタンプ列であり、もちろん行が更新されるたびに変更されるため、挿入/更新/ごとに更新する必要があるため、この列をインデックスに含めるのは設計上の選択として不適切ではないかと考えています.消去?

これにより、n回のインデックス シークではなく n 回のインデックス スキャン発生するため、すべてのデータを 1 回読み取り、regionId でグループ化し、regionId にデータがない行の空のリストを埋める方がよい場合があります。

実際のシナリオはもう少し複雑で、クエリを実行する必要があるテーブル リレーションシップもあります。バージョン クエリに 1 対多の関係を含めることについてはまだ検討していません。

これは主に、インデックスをカバーすることの影響をよりよく理解し、それらをより適切に使用する方法を理解することに関するものです. いずれにせよ、テーブルからすべてのデータを読み取るつもりなので、それらを一度にロードする方がおそらく安価です。ただし、上記のクエリのようにそれらを読み取ると、この単純な関係のない例だけでも、私のコードはずっときれいになります。

編集: 代替 2頭に浮かんだ別のオプションは、 RegionIdに カバー インデックスを作成し、主キー (DatabaseId) を含めることです。

SELECT DatabaseId
FROM TableX WHERE RegionId=1

そして、必要な列を選択する新しいクエリ WHERE DatabaseId IN(list, of, databaseId)

現在のシナリオでは、テーブルには最大数千行しかなく、数百万行ではありません。2 つの (x n ) クエリのネットワーク トラフィックは、おそらくインデックスを使用する利点を上回り、時期尚早な最適化になる可能性があります。

4

0 に答える 0