SQL Server 2005:哪一个更快?条件超过2列或超过2行?

时间:2010-02-09 22:17:25

标签: sql-server-2005 entity-attribute-value sql

Table1
------------
ID
IdColumn1
Idcolumn2

Table2
------------
ID
IdColumn
IdPair

它们都包含相同的数据。

Table1填充了两列,Table2将这些列存储在两行中。

因此,如果Table1包含n行,则Table2将具有2 * n行

哪个查询更快?

select * from Table1 
where IdColumn1 = x or IdColumn2 = x

select * from Table2 where IdColumn = x

我已经选择了Table2方案,到目前为止我有超过400,000行,每天有超过1000个唯一身份访问者。每天在此数据库中添加超过2000行。我的网站继续快速增长。

不要问我为什么有那么多行,他们在网上比赛中玩游戏,而那些行是玩家之间的匹配。

5 个答案:

答案 0 :(得分:2)

我也会选择Table2。

只是为了突出方法的不同,这里是为选项生成的3个执行计划,假设Table1在IdColumn1和IdColumn2上有非聚簇索引,而Table2在IdColumn上有非聚簇索引。 ID是CLUSTERED。表1中的100,000条记录,表2中的200,000条

1)Table1方法在2个id列上使用OR条件:
alt text http://img52.imageshack.us/img52/3264/23430147.png

2)Table1方法,2个语句与UNION ALL组合:
alt text http://img192.imageshack.us/img192/6281/47968640.png

3)表2方法:
alt text http://img52.imageshack.us/img52/2131/72286216.png

表2的计划显然要简单得多。

答案 1 :(得分:1)

我会选择Table2。

使用Table1架构,您至少需要两个索引,一个在IdColumn1上,一个在IdColumn2上,您可以使用以下方法有效地查询:

select * from Table1 where IdColumn1 = x
union all 
select * from Table1 where IdColumn2 = x;

但至少有一个索引是非聚集的,你会有很多逻辑杂耍来识别与玩家相关的所有项目,因为它们可以在IdColumn1或IdColumn2上。只要想想将来会带来3路游戏(3名玩家,添加IdColumn3 ......)。

Table2更好,因为它有一个明确的目的:存储玩家参与的所有游戏,由玩家ID聚集。它可以更简单地进行交互,它可以更简单地构建,并且可以在以后的每场比赛中扩展到更多的玩家。

不确定PairId是什么。您的数据模型是典型的多对多关系,只需将“播放器”替换为“学生”,将“游戏”替换为“课程”,您就会发现您完全符合学生课程的规范数据建模101课程结构(在你的情况下,一个游戏(=课程)恰好可以有2个玩家(=学生),但这是一个细节。你还在谈论典型的3桌关系(1个用于游戏,1个用于玩家,1个对于玩家到游戏的参与)。

答案 2 :(得分:1)

表2实现了Entity-Attribute-Value模型(EAV),这种模型经常被选中,因为该模型比传统的表模型(以及大型关系模型)具有一些优势。 EAV的一个众所周知的优点是基于多个列值的OR搜索既有效又更容易在传统模型中进行编码。

新的SQL Server实现提供的一些新功能也有助于EAV模型。

总的来说, EAV模型对于逻辑模式带来的灵活性以及其性能的其他相关优势更具吸引力,特别是在应用于数据库时超过一百万个实体(即可能有几十万个EAV条目,如果每个实体有很多属性)。
实际上,证明了这一点,几个EAV实现引入了两种模型的混合,其中大多数实体共有的单值属性存储在“头文件”中,而不是存储在EAV列表中。

当然,在OR-ed列值问题的限制性上下文中,两个模型中哪一个更有效的最后一个词取决于数据的有效实现,索引和统计配置文件。 对于较小的EAV表(例如这个具有c.500,000个条目的表),EAV模型可能提供优势,一般情况下

请参阅此相关SO文章:database: EAV pros,cons and alternatives 并且通常扫描few SO articles with the eav tag

答案 3 :(得分:0)

很难说。我认为两者应该有相似的性能,或者第二应该更好,因为idColumn是主键。检查查询执行计划并确保我有适当的索引。

答案 4 :(得分:0)

一个表比另一个表更快的唯一原因是您在表上创建的索引。除非您没有在第一个表(或相反)上创建正确的索引,否则第二个表没有性能优势。

例如,似乎第二个表更快,因为您在表1上的idcolumn1和表2上的idcolumn上创建了一个索引。如果您在idcolumn1上创建了一个索引,而在表1中的idcolumn2上创建了另一个索引,那么您将看到非常相似的表现。

由于表2是重复数据,因此不建议维护此表。每次更新都需要更改两行。

但是,我看到这类数据的数据设计如下所示:

match table
-----------
matchid
additional match information

participants table
------------------
participantid
matchid

在此模式中,每个匹配(以及任何附加数据)在匹配表中有一行,并且您有一个看起来像表2的表。它将参与者与匹配相关联。

然后你只需要对参与者进行选择并将其链接到匹配数据。

我相信这对您的情况来说是最佳做法。