SQL Server视图,祝福还是诅咒?
我曾经与一位禁止使用SQL视图的架构师一起工作。他的主要原因是,视图使一个毫无思想的编码人员过于容易地不必要地包含了联接表,如果该编码员更加努力,则可以完全避免联接表。暗示他鼓励通过复制和粘贴而不是封装在视图中来重复使用代码。
该数据库有将近600个表,并且已高度规范化,因此大多数有用的SQL一定很冗长。
几年后,我从禁令中至少看到一个不好的结果,我们有数百个密集,冗长的存储过程,几乎无法维护。
事后看来,我会说这是一个错误的决定,但是我们对SQL视图有何经验?我们发现它们对性能不利吗?还有其他关于何时合适的想法吗?
解决方案
回答
我们已经回答了自己的问题:
he was encouraging code reuse via copy-and-paste
通过创建视图来重用代码。如果视图的性能较差,那么与在多个位置具有相同的性能较差的代码相比,跟踪起来要容易得多。
回答
我当前的数据库中充斥着无数的小表,每个表不超过5行。好吧,我可以数出它们,但是很混乱。这些表仅保留常量类型值(例如枚举),并且可以很容易地组合到一个表中。然后,我制作了模拟我删除的每个表的视图,以确保向后压缩。很棒。
回答
我们使用视图将所有简单数据导出到csv文件。这简化了编写程序包和将sql嵌入程序包中的过程,这变得麻烦且难以调试。
使用视图,我们可以执行一个视图,并确切地查看导出的内容,没有任何杂物或者未知数。它极大地有助于解决由于数据导出不正确而引起的问题,并将任何复杂的联接隐藏在视图后面。当然,我们使用了基于TERMS的系统中非常古老的遗留系统,该系统可以导出到sql,因此联接比平常要复杂一些。
回答
视图非常适合临时查询,这种查询是DBA在需要快速访问数据以查看系统运行情况时在后台进行的一种查询。
但是它们可能对生产代码不利。部分原因在于,视图所需的索引有点无法预测,因为where子句可以不同,因此很难调优。同样,与使用该视图的单个查询相比,返回的数据通常要多得多。这些查询中的每一个都可以单独加强和调整。
在数据分区的情况下,视图有特定用途,这可能非常有用,因此我并不是说应该完全避免使用它们。我只是说,如果可以用一些存储过程替换视图,那么不用该视图会更好。
回答
视图有一些很好的用途。我已经大量使用它们来进行调优和公开较少标准化的信息集,或者将多个选择的结果进行UNION合并为单个结果集。
显然,任何编程工具都可能会被错误地使用,但根据我的经验,从性能的角度来看,调优的视图不佳会导致任何种类的弊端,以及通过提供显式调优的选择并避免它们所提供的价值,我无法想到复杂的SQL代码的重复可能很重要。
顺便说一句,我从来都不喜欢基于"阻止开发人员伤害自己"的体系结构"规则"。这些规则通常会有意想不到的副作用-我工作的最后一个地方不允许在数据库中使用NULL,因为开发人员可能会忘记检查null。最终迫使我们在针对数据库构建的所有软件中解决" 1/1/1900"日期和整数默认为" 0"的问题,并引入了由开发人员在NULL为适当值的地方工作所引起的大量错误。 。
回答
像所有功能一样,视图也有其自身的阴暗面。但是,我们不能因为有人编写了性能不佳的代码而归咎于视图。此外,视图可以限制某些列的显示范围,并提供额外的安全性。
回答
让我们看看我是否可以提出一个la脚的类比...
"我不需要十字螺丝刀。我带一个平头和一个研磨机!"
漫不经心地取消视图将长期引起痛苦。一方面,调试和修改单个视图定义比交付修改后的代码要容易得多。
回答
到目前为止尚未提及的一件事是使用视图向最终用户提供数据的逻辑图片以进行临时报告或者类似报告。
这有两个优点:
- 为了使用户能够包含他们期望的数据的单个"表",而不是要求相对非技术的用户来设计潜在的复杂联接(因为数据库已规范化)
- 它提供了一种方式,允许一定程度的临时访问,而无需将数据或者结构暴露给最终用户。
即使使用非临时报告,有时也很容易为包含相关数据的报告系统提供视图,从而将数据的产生与数据的呈现完全分开。
回答
前一段时间,我尝试维护使用从视图构建的视图中构建视图的代码。
通常,我通常更喜欢直接使用表,尤其是对于那些主要关注速度的Web应用程序。直接访问表时,我们可以调整SQL查询以达到最佳性能。 "预编译" /缓存的工作计划可能是视图的优势之一,但是在许多情况下,使用所有给定参数的即时编译以及考虑中的where子句将导致整体处理更快。
但是,如果使用得当,则不能完全排除观点。例如,如果需要,可以使用将" users"表与" users_status"表结合在一起的视图,以获取每种状态的文字说明。但是,如果不需要解释,请使用"用户"表,而不是视图。一如既往:用脑!
回答
不是很喜欢观点的人(不记得我上次写的观点了),但也不会完全禁止它们。如果数据库允许我们将索引放在视图上而不只是在表上,则通常可以将性能提高很多,从而使索引更好。如果使用的是视图,请确保对它们进行索引。
我真的只看到需要对数据进行分区的视图和对应用程序至关重要的极其复杂的联接的需求(这里的财务报告思考,从同一数据集开始的所有事情都至关重要)。我确实知道有些报告工具似乎更喜欢视图而不是存储过程。
我是一个强烈的支持者,在特定情况下,绝不要返回比我们需要的记录或者字段还要多的内容,而视图的过度使用往往会使人们返回的字段(以及太多的情况下,太多的联接)超出他们的需求,这会浪费系统资源。
我还倾向于看到依赖视图的人(不是视图的开发人员,而是仅使用视图的人)通常不太了解数据库(因此,如果不使用视图,他们将得到错误的联接),并且对我而言,对于针对数据库编写良好的代码至关重要。我希望人们了解他们要求数据库执行的操作,而不是依赖于视图的某些黑匣子。那当然是所有个人意见,里程可能会有所不同。
像BlaM一样,我个人并不认为它们比存储的proc更易于维护。
于2010年10月编辑,添加了:
自从我最初写这篇文章以来,我就曾经有过使用由沉迷于使用视图的人设计的几个数据库的机会。更糟糕的是,他们使用的视图称为视图的视图称为视图(以至于最终我们达到了可以调用的表数量的极限)。这是一场表演梦night。在一个视图中只花了8分钟即可对记录进行简单的计数(*),而花费更长的时间来获取数据。如果使用视图,请谨慎使用调用其他视图的视图。我们将要建立一个在正常的生产性能负载下可能无法正常工作的系统。在SQL Server中,我们只能索引不调用其他视图的视图,因此,当我们在链中使用视图时,最终会发生的事情是必须为每个视图构建整个记录集,而直到我们到达最后一个是应用where子句条件。我们可能需要生成数百万条记录,才能查看三个。当我们实际上只需要连接一次同一表时,我们可能会连接6次,因此返回的列可能比最终结果集中需要的列多得多。