1
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 行。我的网站保持快速增长。

不要问我为什么有这么多排,他们玩的是在线比赛,那些排是玩家之间的比赛。

4

5 回答 5

2

我也会选择Table2。

只是为了强调方法的差异,这里是为选项生成的 3 个执行计划,假设 Table1 在 IdColumn1 和 IdColumn2 上具有非聚集索引,并且 Table2 在 IdColumn 上具有非聚集索引。ID 是集群的。Table1 100,000 条记录,Table2 200,000 条记录

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

2) Table1 方法与 2 个语句与 UNION ALL 相结合:
替代文本 http://img192.imageshack.us/img192/6281/47968640.png

3)Table2方法:
替代文字http://img52.imageshack.us/img52/2131/72286216.png

Table2的方案显然要简单很多。

于 2010-02-09T22:50:33.997 回答
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 是什么。您的数据模型是典型的多对多关系,只需将 'Player' 替换为 'Student' 和 'Game' 替换为 'Course' ,您会发现您完全符合 Student-Course 的规范 Data Modeling 101 课程结构(在您的情况下,一个游戏(=课程)恰好可以有 2 个玩家(=学生),但这是一个细节。您仍然在谈论典型的 3 表关系(1 个用于游戏,1 个用于玩家,一个用于玩家对游戏的参与)。

于 2010-02-09T22:27:59.643 回答
1

表 2 实现了实体-属性-值模型 (EAV),通常选择该模型是因为该模型提供了优于传统表模型(以及整个关系模型)的一些优势。EAV 的已知优势之一是基于多列值的 OR 搜索既高效又易于在传统模型中进行编码。

此外,较新的 SQL 服务器实现提供的一些新功能也有助于 EAV 模型。

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

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

请参阅此相关的 SO 文章:数据库:EAV 的优点、缺点和替代方案 ,并通常扫描一些带有 eav 标签的 SO 文章

于 2010-02-09T22:34:00.500 回答
0

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

于 2010-02-09T22:23:36.380 回答
0

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

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

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

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

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

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

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

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

我相信这将是适合您情况的最佳做法。

于 2010-02-09T22:24:03.757 回答