我有一个使用类似 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
);
它映射到实体框架模型。我正在处理每个多达 1000 万条记录的大型数据集。
我的问题是,我需要找到特定玩家在任何给定位置上刺痛的所有手牌(加上一些其他过滤器,如日期范围)。
虽然我可以非常快速地扫描数据库,以从单个表中查找数据,例如:
//[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);
我可以提取什么巧妙的技巧、合并查询和代码(例如,使用本地缓存)以使其运行最有效?我正在使用 System.Data.SQLite 提供程序。
也许我应该在 Position 表中添加冗余 DataSetID,然后我只能在 Position 表上进行主要查询?稍后,当我将获得所有匹配手的 ID 时,添加附加条件(如日期检查)应该会更快