1

在 Sql 2008 上(之前是 05 年),我在生产中使用了将近 3 年的数据库。一直很好,但性能不是很好。所以我正在调整架构和查询以帮助加快一些事情。此外,每张主表包含大约 1-3 个轧机行(以提供对大小的 ua 估计)。

这是一个示例数据库图(Soz,在 NDA 下,所以我无法显示原件):-

替代文字 http://img11.imageshack.us/img11/4608/dbschemaexample.png

注意事项(与我的问题直接相关):-

  • 车辆可以有 0 (NULL) 或 1 个 Radio。(左外连接)
  • 车辆可以有 0 个(NULL)或 1 个杯托(左外连接)
  • 车辆有 1 种轮胎类型(内连接)。

首先,这看起来像一个规范化的数据库模式。我很烂,DB理论,所以我猜这是3NF(至少)......著名的遗言:)

现在,这正在扼杀我的数据库性能,因为这两个外连接和内连接被调用了很多,并且在许多语句中还有一些连接。

为了尝试解决这个问题,我想我可以尝试indexed view。创建视图是小菜一碟。但是索引它不起作用->无法使用连接或自引用表创建索引视图(也是另一个问题:()。

所以,我已经哭了好几个小时(和/wrists染了头发写了一首关于它的 emo 歌曲并将它放在 myfailspace 上)并做了以下事情......

  1. 在每个“可选”外部连接表中添加了一个新行(在本例中为 Radios 和 CupHolders)。ID = 0,其余数据 = 'Unknown Blah' 或 0。
  2. 更新父表,使任何 NULL 数据现在都有一个 0。
  3. 将关系从外部联接更新到内部联接。

现在,这行得通。我什至可以制作索引视图,现在速度非常快。

所以……我很痛苦。这与我所学的一切背道而驰。我觉得脏。独自的。已感染。

这是一件坏事吗?这是为了性能而对数据库进行非规范化的常见场景吗?

我很想对此有一些想法,请:)

PS。谷歌随机找到的那些图片——所以不是我。

4

4 回答 4

2

空值通常不用于索引。您所做的是提供一个标记值,以便该列始终具有一个值,从而可以更有效地使用您的索引。

你也没有改变你的数据库的结构,所以我不会称之为非规范化。我已经使用日期值完成了此操作,其中您有一个“结束日期”空值表示尚未结束。相反,我将其设置为将来允许索引的已知日期方式。

我认为这很好。

于 2009-07-09T01:25:10.127 回答
1

数据库应始终在 3NF 中设计和初始实施。但是世界是一个现实的地方,而不是理想的地方,出于性能原因,可以恢复到 2NF(甚至 1NF)。不要为此自责,实用主义在现实世界中总是胜过教条主义。

您的解决方案,如果它提高了性能,是一个很好的解决方案。拥有一台没有人制造并且没有任何功能的实际收音机(例如)的想法并不是一个糟糕的想法 - 以前已经做过很多了,相信我:-) 使用该字段作为 NULL 的唯一原因是查看哪些车辆没有收音机,这些查询之间几乎没有区别:

select Registration from vehicles where RadioId is null
select Registration from vehicles where RadioId = 0

我的第一个想法是简单地将四个表合并为一个并挂起重复数据问题。DBMS 的大多数问题源于性能不佳而不是存储空间不足。

如果您当前的非规范化模式也变得缓慢,也许可以将其作为您的后备位置。

于 2009-07-09T01:35:45.500 回答
0

“......所以我正在调整架构和查询以帮助加快一些事情......” - 我会对此有所不同。看来你正在放慢速度。(只是在开玩笑。)

我喜欢数据库程序员博客。他有两列支持和反对规范化,您可能会发现它们很有帮助:

  1. http://database-programmer.blogspot.com/2008/10/argument-for-normalization.html
  2. http://database-programmer.blogspot.com/2008/10/argument-for-denormalization.html

我不是 DBA,但我认为证据就在您的眼前:性能更差。我看不出将这些 1:1 关系拆分为单独的表格有什么好处,但我很乐意接受指导。

在我更改任何内容之前,我会要求 SQL Server 对每个缓慢的查询进行解释计划,并使用该信息来准确查看应该更改的内容。不要猜测,因为规范化大师告诉过你。获取数据以备份您正在做的事情。您正在做的事情听起来像是在没有分析的情况下优化中间层代码。直觉不是很准确。

于 2009-07-09T01:21:09.177 回答
0

我遇到了同样的表现与学术卓越的问题。我们有一个包含 300 列和 91000 条记录的客户数据库的大视图。我们使用外部连接来创建视图,性能很差。我们已经考虑通过在我们加入的列(而不是 null)上放入值为 0 的虚拟记录来更改内部连接,以在视图上启用唯一索引。

我必须同意,如果性能很重要,有时必须做一些奇怪的事情来实现它。最终,那些支付我们账单的人并不关心架构是否完美。

于 2009-09-09T21:40:40.500 回答