在存储过程中使用视图而不是表?

时间:2011-02-05 15:31:28

标签: sql database database-design stored-procedures views

查询视图而不是存储过程中的原始表是一种好习惯吗? (即使视图不提供任何不同的数据)

我总是认为这可能是一个好主意,因为它是一个额外的抽象层,类似于在类函数中使用属性而不是成员变量。

但是现在我正在查看ASP.NET成员资格提供程序创建的存储过程,它们总是直接查询表。

我知道您在使用视图时无法轻松插入数据,但如果存储过程仅查询数据,您是否仍应直接使用表?如果是的话,主要原因是什么? (性能?)

4 个答案:

答案 0 :(得分:6)

视图只是一个扩展为外部查询的宏。

如果你的视图包含多个连接,那么当你加入if到其他视图时,当你在存储过程的SQL中实际看到3个JOIN时,你突然有20或30路JOIN。您还会发现每个查询都不同:为什么要为每个查询加入相同的20或30个表?

通常,除非对视图进行索引/实现并且优化器可以使用它,否则没有任何好处。

诸如对视图屏蔽的单个表进行计算的想法应该在计算列中:为什么要继续计算它?对于视图中多个表的计算,应对其进行索引。

使用存储过程已经意味着没有基表访问权限(所有权链接)。

有很好的视图用途可以避免用户直接访问表,或掩盖模式更改,或提供一些基本的安全性(例如基于SUSER_SNAME),但不能用于性能或思想

答案 1 :(得分:3)

不同的数据库优化器以不同的方式优化查询,因此它不是一个简单的答案。但通常添加一个抽象层可以(并非绝对)阻止优化器正确使用索引。

在Sql Server中,如果你有一个包含如下调用的where子句:

  • IS NULL
  • LIKE'%something'
  • NOT EXISTS

它使它成为non-sargable查询,即不使用索引的查询 - 或以次优方式使用它们。

我猜想使用视图也会影响sarg。我将去测试这个(在Sql Server中) - 我将在5分钟后回来。

修改

我猜答案是'它取决于'并且您需要启用查询执行计划以确保,我所做的以下测试显示在查询基于表的简单视图和简单查询之间没有区别基础表。但它需要进一步测试,因为复杂的观点可能采取不同的行动。

Sql Execution Plan for accessing a simple view compared to the table directly

答案 2 :(得分:0)

我在这两种情况下使用了存储过程中的视图:

1 - 对于多个程序中需要的复杂连接或条件

2 - 替换重命名的表格。例如,我有两个表,称为“成员”和“非成员”。我后来决定将这些组合成一个“用户”表。为了避免修改我曾写过的每个proc,我创建了名为'member'和'non_member'的视图,它们使用where子句来适当地过滤'user'表。所有的过程都像往常一样运行而没有变化。我有时间可以更改它们以直接访问新表。

答案 3 :(得分:0)

在SQL Server中(至少),我的理解是存储过程在编译时进行了优化,因此通常比视图更有效。我不确定,但我怀疑通过对视图执行SPRC,您可能会失去通过这种方式获得的任何优化。

此外,为什么?如前一张海报所说,如果您所包含的一个或多个视图本身由众多连接组成,那么您可能正在执行比您需要更多的连接,这并不明显。

另外,我的理解是使用视图的主要原因之一是以用户可以使用的格式呈现表数据,同时保护表数据免于意外更改。由于SPROC的结果集不受INSERTS和UPDATES的限制,因此这一点没有实际意义。

由于设计的存储过程接受参数,不允许用户直接与表数据交互,并且可以执行您可能在视图中使用的任何查询逻辑(加上更多),在我看来(除了一些例外)可能这样做的主要原因是使CODING更容易,性能和可维护性的潜在成本(如果有人更改其中一个视图,而没有意识到您的SPROC依赖它?)。

我建议将其全部编入SPROC,除非有令人信服的理由不这样做。 。