Sql server 如果我';为了性能,我正在销毁我的数据库模式:(

Sql server 如果我';为了性能,我正在销毁我的数据库模式:(,sql-server,database-design,normalization,denormalization,Sql Server,Database Design,Normalization,Denormalization,我已经有一个数据库在Sql 2008上生产了近3年(2005年,在那之前)。它很好,但性能不是很好。所以我正在调整模式和查询,以帮助加快一些事情。此外,许多主表包含大约1-3百万行,每个表(给你一个大小估计) 这是一个示例数据库图(Soz,在NDA下,因此我无法显示原始数据库图):- 注意事项(与我的问题直接相关):- 车辆可以有0(空)或1个收音机。(左外连接) 一辆车可以有0个(空)或1个杯托(左外连接) 车辆有1个轮胎类型(内部连接) 首先,这看起来像一个。我很烂和DB理论,所以我猜

我已经有一个数据库在Sql 2008上生产了近3年(2005年,在那之前)。它很好,但性能不是很好。所以我正在调整模式和查询,以帮助加快一些事情。此外,许多主表包含大约1-3百万行,每个表(给你一个大小估计)

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

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

  • 车辆可以有0(空)或1个收音机。(左外连接)
  • 一辆车可以有0个(空)或1个杯托(左外连接)
  • 车辆有1个轮胎类型(内部连接)
首先,这看起来像一个。我很烂和DB理论,所以我猜这是3NF(至少)…著名的遗言:)

现在,这正在破坏我的数据库性能,因为这两个外部联接和内部联接被调用很多,而且在许多语句中还有一些联接

为了解决这个问题,我想我可以尝试创建索引视图。创建视图是小菜一碟。但是为它编制索引不起作用->无法创建带有联接或自引用表的索引视图(还有另一个问题:())

所以,我哭了好几个小时(而且,关于它,我把它放在我的FailSpace上),然后做了以下事情

  • 在每个“可选”外部联接表(在本例中为收音机和杯托)中添加了新行。ID=0,其余数据=“Unknown Blah”或0
  • 更新父表,以便所有空数据现在都具有0
  • 将关系从外部联接更新为内部联接
  • 现在,这就行了。我甚至可以创建我的索引视图,现在速度非常快

    所以…我很痛苦。这与我所学的一切背道而驰。我感到肮脏。孤独。被感染

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

    我想听听你的想法:)

    顺便说一句,谷歌随机找到的那些图片——我不是。

    “…所以我正在调整模式和查询,以帮助加快某些事情的速度…”对此我不敢苟同。看来你在放慢速度。(只是开玩笑。)

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

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


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

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

    您也没有更改数据库的结构,所以我不会称之为非规范化。我已经用日期值完成了,其中“结束日期”null表示尚未结束。取而代之的是,我把它做成了一种未来已知的日期方式,它允许建立索引

    我认为这很好。

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

    如果您的解决方案能够提高性能,那么它就是一个好的解决方案。有一个实际的收音机(例如),没有人制造,没有任何功能,这不是一个坏主意-它以前做过很多,相信我:-)您将该字段用作NULL的唯一原因是查看哪些车辆没有收音机,这些查询之间没有什么区别:

    select Registration from vehicles where RadioId is null
    select Registration from vehicles where RadioId = 0
    
    我的第一个想法是简单地将四个表合并成一个表,并挂起重复数据问题。DBMS的大多数问题源于性能差,而不是存储空间低


    如果你当前的非标准化模式也变得缓慢,那么也许可以将其作为你的退路。

    我遇到了同样的问题,即绩效与学术卓越。我们有一个客户数据库的大视图,其中有300列和91000条记录。我们使用外部联接来创建视图,性能非常差。我们已经考虑过通过在我们连接的列(而不是null)上放入值为零的伪记录来更改为内部连接,以便在视图上启用唯一索引


    我必须同意,如果表现很重要,有时必须做一些奇怪的事情才能让它发生。最终,那些为我们付账的人并不在乎体系结构是否完美。

    你是说内部连接比外部连接快吗?它不应该是-你能举一个例子说明什么是慢的吗?顺便说一句:你没有影响你的规范化-关于在表中使用null有很多争论,有些人会认为你的更改是一种改进。你在现有的Vehicles表上有什么索引。一个运行缓慢的查询示例也很有用。@TonyLee-我通常发现内部连接总是比外部连接快@Evillyry-我会在PK和每个FK上有索引,并有各种排列。一般来说,outer将返回更多行(那些为空的行),但在您的情况下,不会这样。我猜您是如何通过其他方式修改select以提高性能的。我几乎每次在SSMS中运行查询时都会使用可视化的查询计划。通过两个表之间的连接,我将得到200万行连接另一个大量的表。我在p上也有很多索引