2016-11-08 6 views
2

私はaspnet-core、ef-coreとSQLサーバを使用しています。私には「注文」エンティティがあります。私はordersテーブルが大きいと予想しているので、最も頻繁なクエリは特定の顧客のアクティブな注文のみを取得します(アクティブな注文はテーブル全体のほんの一部です)。私はクエリの速度を最適化したいのですが、ef-core-boolインデックスと履歴テーブル

1)私はこれまでにこれをやっていないのでこれが可能かどうかわかりませんが、IsActiveという名前のブール列を作成してそれをインデックスにすることを考えていましたアクティブな注文のみを照会する方が高速になります。

2)注文が有効になっていない場合は、注文を別のテーブル、つまりHistoricalOrdersに移動し、注文テーブルを小さく保ちます。

どちらの方が良い結果になるのでしょうか?それとも良い解決策ではないのでしょうか。

+0

現時点では、linqクエリを表示できますか? – Sampath

+0

@Sampath Havenはまだ書いていませんが、最初のアプローチでは、 _context.Set ().Where(o => o.IsActive == true) –

答えて

-1

新しいテーブルHistoricalOrdersについて考える前に、カラム名IsActiveを作成し、データでテストしてください。インデックスカラムとして作成する必要はありません。インデックスがストレージを使い果たし、書き込みが遅くなります。インデックスを作成するときには非常に注意する必要があります。データをクエリすると、以下のようになります。データ選択(またはフィルタ)がSQLスレーブ側(IQueryable)で行われる以下のクエリでは、速い。

注:も使用してください。AsNoTracking()も使用してください。

var activeOrders =_context.Set<Orders>().Where(o => o.IsActive == true).AsNoTracking() 
.ToList(); 

参考:AsNoTracking()

+0

のようなインデックスが必要です。 'IsActive'カラムはテーブルスキャンを避けるために使用します。 – thoean

+0

インデックスがストレージを使い果たし、書き込みや更新が遅くなるので、インデックスを作成するときには非常に注意が必要です。@thoean – Sampath

+2

@usr sampathは私の質問で言及した2つのアプローチのどちらかを決定するのに役立ちました。しかし、私は他の解決策を聞くことに興味があります。代替案をお勧めしますか? –

0

あなたは寒さのデータを離れてパーティションを作成する場合は、主要なブールインデックス列はそれを行うための有効な方法です。この列は、ホット/コールドパーティションにするすべてのインデックスに追加する必要があります。これには、クラスタード・インデックスも含まれます。これはかなり厄介です。照会オプティマイザーでは、ダミー述部where IsActive IN (0, 1)を追加して、その索引を引き続き検索できるようにする必要があります。もちろん、これは寒さのデータにも触れます。だから、IsActiveの具体的な値を知っているか、最初に1の値を試して、それが99%の時間と一致することを確認する必要があります。

スキーマによっては、これは実用的ではありません。私はこれについて良い事例は見たことがないが、私はそれが存在すると確信している。

別のやり方では、パーティション分割を使用することです。ここでは、問合せオプティマイザは複数のパーティションをプロービングするのに使用されますが、再びコールド・データを検証する必要はありません。何も見つからない場合でも、ページがメモリにプルされ、パーティション化の問題が解決されます。

履歴表の考え方(例:HistoricalOrders)は、さまざまな服で同じことです。

だから、あなたが必要とするこの作品にするために:すべてのあなたが(おそらくすべて)に関するものです、インデックス、またはパーティションを変更し

  1. を、または履歴テーブルを作成します。
  2. ほとんどの場合、コールドパーティションをプローブする必要はありません。

私は(2)ほとんどの場合それを殺すと思う。

3つのソリューションの中で、最も簡単なので、私はおそらくインデックスソリューションを選択します。いつでも間違ったクエリを書くことによって人々が間違いを犯すことを心配しているなら、私は別のテーブルを選ぶでしょう。それは間違いを難しくしますが、コードはかなり厄介です。

多くのインデックスは既に自然にパーティション化されていることに注意してください。 ID列または増加する日時列の索引は、最後は熱く、別の場所は寒いです。 (OrderStatus INT, CreateDateTime datetime2)のインデックスは注文ステータスごとに1つのホットスポットを持ち、それ以外の場合は寒いでしょう。だからすでに解決済みです。

Some further discussion.