【问题标题】:Using views instead of tables in stored procedures?在存储过程中使用视图而不是表?
【发布时间】:2011-06-21 22:02:14
【问题描述】:

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

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

但现在我正在查看由 ASP.NET Membership Provider 创建的存储过程,它们总是直接查询表。

我知道在使用视图的时候不能很方便地插入数据,但是如果存储过程只查询数据,你还应该直接使用表吗?如果是,主要原因是什么? (性能?)

【问题讨论】:

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


    【解决方案1】:

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

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

    • 为空
    • LIKE '%something'
    • 不存在

    它使它成为non-sargable 查询,即不使用索引的查询 - 或使用它们的方式不是最理想的。

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

    编辑

    我猜答案是“视情况而定”,并且您需要打开查询执行计划以确保,我所做的以下测试显示基于表查询简单视图和简单查询之间没有区别基础表。但它需要进一步测试,因为复杂的视图可能会有不同的表现。

    【讨论】:

    • “我会去测试这个(在 Sql Server 中)——我会在 5 分钟后回来。” - 嘿,很酷,谢谢。我会在这里等着。 :D
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

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

      视图有很好的用途,可以避免用户直接访问表,或者屏蔽架构更改,或者提供一些基本的安全性(例如基于 SUSER_SNAME),但不是为了性能或理念

      【讨论】:

        【解决方案4】:

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

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

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-05-11
          • 1970-01-01
          • 1970-01-01
          • 2011-12-11
          • 1970-01-01
          • 2011-08-13
          相关资源
          最近更新 更多