2011-01-27 78 views
1

我有一个大表(100000+行),其中有4列具有相同的概念值。SQLServer将多个列索引为一个结果

说一个记录代表球员他们的名字都在列A,B,C和D 和A + B扮演VS C + D。

当我查询该表所扮演的所有比赛之间的竞争一个名叫“DOE”的家伙,我需要检查名称的4列值:

......其中(列A像'DOE%'或列B像'DOE%'或列C像'DOE% '或D列'DOE%') AND ...其他条件...

而且由于表是巨大的,我需要一种方法来索引所有这些4 c olumns。

我知道我可以创建一个辅助表与他的位置A,B,C或d和主表的行ID一起存储每个球员的名字,但我怀疑应该有一个更好的办法...

任何来自SQLServer大师的线索?

回答

3

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

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

+0

我认为在1个查询中,SQLServer只选择1个索引,其余部分是从部分结果处理的 - 在我的情况下,在列A上的“OR”hance索引将无助于B,C或D上的选择。 ..? – 2011-01-27 13:47:10

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 

你可以用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 
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)查询?选择... from playerGames其中playerId = X

3)目前的设计只允许一个简单的查询,找到位置A,B,C或D的所有玩家,而且这仍然很简单:选择...... from ... where position ='A'

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