同様の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 を取得するときに、追加の条件 (日付の確認など) を追加する方が速いはずです。