只需在每列上放一个索引(总共4个索引)。
这样,服务器可以查询每个索引并根据条件将结果放在一起。这允许广泛的查询,并且仍然相当快。
"I know I can create a secondary table storing each player name together with his position A, B, C or D and the main table's RowID, but I suspect there should be a better way..."
在关系数据库中 是 更好的方式。原因是,它使您的应用程序代码更简单,并且您的DBA函数更简单:
1)索引问题?关于playerID的索引。
2)查询?从playerGames中选择...其中playerId = X.
3)当前的设计只允许一个简单的查询,找到位置A,B,C或D的所有玩家,这仍然很容易:选择......来自......其中position ='A'
这就是为什么数据库大师会经常试图指出规范化不是为了满足一些模糊的理论而做的一些苦差事,但实际上规范化会使整个系统变得更简单。
我会在每个列上放一个索引,并将ID作为包含的列,如@ttoni所述,然后在id上创建一个覆盖索引并包含4列,然后运行此查询:
declare @string varchar(50) set @string='Karen' select a.ID A, B, C, D from dbo.Players a inner join ( select ID from dbo.Players where A = @string union all select ID from dbo.Players where B = @string union all select ID from dbo.Players where C = @string union all select ID from dbo.Players where D = @string ) b on a.ID=b.ID
你可以用like来切换等号,然后只需将百分比添加到变量的末尾,如果你这样做,它只需要对sql server进行一些处理。
这是第一个索引:
CREATE NONCLUSTERED INDEX [IDX_A] ON [dbo].[Players] ( [A] ASC ) INCLUDE ( [ID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO
这是覆盖指数:
CREATE NONCLUSTERED INDEX [IDX_All] ON [dbo].[Players] ( [ID] ASC ) INCLUDE ( [A], [B], [C], [D]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO