单表与联接双重结构的表现

时间:2010-02-04 08:34:28

标签: sql database linq performance structure

这不是关于使用其他工具的问题。这不是关于使用不同数据结构的问题。这是关于为什么的问题我看到了什么 - 请在回答之前阅读到最后。谢谢。

THE STORY

我有一个表有一个条件的表,记录不会被删除。相反,记录被标记为不活动(有字段),在这种情况下,所有字段(标识符除外,这些isActive字段)都被视为无关。

有关标识符的更多信息 - 有两个字段:

  • id - int,主键,群集
  • name - unique,varchar,external index

如何进行更新(我使用C#/ Linq / MSSQL2005):我根据名称获取记录,然后更改必填字段并提交更改,以便执行更新(UPDATE使用id,而不是名称)

但是存储存在问题。那么为什么不将这个表分成双重结构 - “header”表(id,name,isActive)和数据表(id,其余字段)。如果存储有问题,我们可以删除数据表中的所有记录(对于isActive = false)。

编辑(由Shimmy提供):LINQ使用join不检索标头+数据。数据记录按需加载(这总是因为代码而发生)。

评论(海报):AFAIR没有加入,所以这是无关紧要的。标题的数据是手动加载的。见下文。

表演 - (我的)理论

现在,性能怎么样?哪一个会更快?假设您在两个表中都有10000条记录(单个,标题,数据),并逐个更新它们(所有3个表) - 字段isActive和“data”字段中的某些字段。

我的计算是/是:

  • mono table - 使用外部索引进行搜索,然后跳转到结构中,获取所有数据,使用主键进行更新。

  • 双表 - 使用外部索引搜索,跳转到表头表,获取所有数据,使用数据表上的主键搜索(此处没有跳转,它是聚簇索引),获取所有数据,更新两个表都使用主键。

所以,对我来说单声道结构应该更快,因为在双重情况下我有相同的操作加上一些额外的。

结果

无论我做什么,更新,选择,插入,双重结构要么稍微好一点(速度)要么快30%。现在我都感到困惑 - 我会理解我是插入/更新/只选择标题记录,但在每种情况下都使用数据记录。

问题 - 为什么/如何使双重结构更快?

3 个答案:

答案 0 :(得分:1)

我认为这一切都归结为获取,插入和更新的数据量。

SELECT case - 在双表配置中,您获取的数据较少。数据库运行时主要由I / O时间决定,因此在单表配置中的每一行上复制“标题”字段意味着您必须反复读取相同的数据。在双表配置中,您只能读取一次标题数据。

INSERT案例 - 与上述类似,但与编写数据而非阅读相关。

更新案例 - 您的代码更新了“isActive”字段,如果我已正确读取该字段,则该字段是“标题”字段的一部分。在单表配置中,您要强制为每个“isActive”更改更新许多行。在双表配置中,您只更新每个“isActive”更改的单个标题行。

我认为这是一个过早优化的案例。我觉得你明白根据数据规范化规则,双表配置“更好” - 但是因为单表情况似乎会提供更好的性能,你想要使用该设计。值得庆幸的是,您花时间测试会发生什么,并发现观察到的性能与您的预期不符。 好工作!我希望更多人会花时间像这样测试一下。我认为这里要学到的教训是数据规范化是一件好事。

请记住,优化某些内容的最佳时间是从不!当您遇到观察到的性能问题时,优化事物的第二个最佳时间是。优化的最差时间是在分析期间。

我希望这会有所帮助。

答案 1 :(得分:1)

假设:数据库的SQL Server。

Sql Server在窄表而不是宽表上的性能往往更高。虽然对于诸如大型机之类的东西可能并非如此。

这确实指向规范化,直到您决定不出于性能原因,并且在这种情况下,非规范化表更有效的假设是不正确的。可以在资源中更好地管理规范化结构,而不是在此环境中进行非规范化。我怀疑(没有可信的基础)资源(硬件,多处理器,线程等)使规范化结构更快,因为更多的东西同时完成。

答案 2 :(得分:0)

你看过这两个查询计划吗?这通常会让它消失。

对于推测,表格中行的大小会影响扫描速度。较小的行意味着更多行适合数据页。查询首当其冲的是I / O时间,因此使用两个较小的表会大大减少您在索引中筛选的数据量。

此外,锁更精细 - 第一次更新可以写入table1,然后第二次更新可以在您完成table2时写入table1。