SQLServer为一个结果索引多个列

时间:2011-01-27 09:53:23

标签: sql-server indexing

我有一张大表(100000多行),其中有4列具有相同的概念值。

假设某条记录代表名称在A,B,C和D列中的玩家之间的竞争。 A + B和C + D比赛。

当我查询该表以查找名为“DOE”的人所玩的所有比赛时,我需要检查名称的4列值:

...其中(A栏如'DOE%'或B栏如'DOE%'或C栏如'DOE%'或D栏如'DOE%') 和......其他条件......

由于表格很大,我需要一种方法来索引所有这4列。

我知道我可以创建一个辅助表来存储每个玩家的名字以及他的位置A,B,C或D以及主表的RowID,但我怀疑应该有更好的方法......

来自SQLServer大师的任何线索?

3 个答案:

答案 0 :(得分:3)

只需在每列上添加一个索引(总共4个索引)。

这样服务器可以查询每个索引并根据条件将结果放在一起。这允许广泛的查询,并且仍然相当快。

答案 1 :(得分:1)

"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'

这就是为什么数据库大师会经常试图指出规范化不是为了满足一些模糊理论而做的一些苦差事,但实际上规范化会使整个系统变得更简单。

答案 2 :(得分:0)

我会在每个列上放一个索引,并将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

你可以用等号切换等号,然后只将百分比添加到变量的末尾,如果你这样做,只需要对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