0

同様のDDLで構築されたデータベース(SQLite)があります:

                                    CREATE TABLE [Player] (
                                        [PlayerID] INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL,
                                        [Name] TEXT  UNIQUE NULL
                                        );
                                    CREATE TABLE [Position] (
                                        [PlayerID] INTEGER  NOT NULL,
                                        [SingleHandID] INTEGER  NOT NULL,
                                        [Position] INTEGER  NULL,
                                        PRIMARY KEY ([PlayerID],[SingleHandID])
                                        );
                                    CREATE TABLE [SingleHand] (
                                        [SingleHandID] INTEGER  NOT NULL PRIMARY KEY AUTOINCREMENT,
                                        [Stake] FLOAT  NULL,
                                        [Date] DATE  NULL,
                                        DataSetID INTEGER NULL
                                        [IsPreflopAllIn] BOOLEAN  NULL
                                        );

                                    CREATE UNIQUE INDEX [NameIndex] ON [Player](
                                        [Name]  ASC

                                    CREATE INDEX [DataSetIndex] ON [SingleHand](
                                    [DataSetID]  ASC
                                    );

Entity Framework モデルにマッピングされます。それぞれ最大 1,000 万レコードの大規模なデータ セットに取り組んでいます。

私の問題は、特定のプレイヤーが特定のポジション (および日付範囲などの他のフィルター) に刺されているすべてのハンドを見つける必要があることです。

データベースを非常にすばやくスキャンして、単一のテーブルからデータを見つけることができます。次に例を示します。

//[playerIDs and selectedPos are cashed in memory]

context.Positions.Where(p => playerIDs.Contains(p.PlayerID) && selectedPos.Contains(p.Position)).Select(p => p.SingleHandID).Take(maxHands ?? 1);

テーブル間の結合を行う必要がある場合、実行が非常に遅くなります。次に例を示します。

//accesing both Position and SingleHand table
context.Positions.Where(p => playerIDs.Contains(p.PlayerID) && selectedPos.Contains(p.Position) && p.SingleHand.DataSetID == dataSetNumber).Select(p => p.SingleHandID).Take(maxHands ?? 1);

この実行を最も効率的にするには、どの巧妙なトリック、comining クエリ、およびコード (ローカル キャッシュを使用するなど) をプルできますか? System.Data.SQLite プロバイダーを使用しています。

冗長な DataSetID を Position テーブルに追加する必要があるかもしれません。そうすれば、Position テーブルでのみメイン クエリを実行できますか? 後で、一致するすべてのハンドの ID を取得するときに、追加の条件 (日付の確認など) を追加する方が速いはずです。

4

1 に答える 1

0

新しいインデックスを作成します。

CREATE INDEX [DataSetIndex2] ON [SingleHand](
    [SingleHandID] ASC,
    [DataSetID]  ASC
);

それは大いに役立つはずです。

次のようなこともできます。

context.Positions
  .Where(p => playerIDs.Contains(p.PlayerID) && SelectedPos.Contains(p.Position))
  .Select(p => p.SingleHandID)
.Intersect(context.SingleHand
   .Where(s=>s.DataSetId==dataSetNumber)
   .Select(s=>s.SingleHandID))
.Take(maxHands ?? 1);
于 2013-07-03T16:53:15.640 に答える