【问题标题】:SQL - CTE vs VIEWSQL - CTE 与 VIEW
【发布时间】:2015-09-04 06:50:36
【问题描述】:

我的问题是 SQL 中的CTEView 有什么区别。我的意思是在哪种情况下我应该使用CTE,在哪种情况下应该使用View。我知道两者都是某种虚拟表,但我无法区分它们的用途。

我发现了一个类似的问题here,但它是关于性能的。

更新 1:

例如:我有一个充满交易的数据库(tbl_trade)。我需要从 350 万条记录中仅选择从当前月份到当前时间打开的交易,然后操作数据(在虚拟表上使用不同的查询 - 这看起来像查看)。这里的问题是我想要一个 3-4 列的 SUM,然后我需要 SUM 一些列并使用结果创建一个虚拟列(看起来像 CTE)。

例如:tbl_trade 具有列:profitbonusexpenses。 我需要SUM(profit),SUM(bonus),SUM(expenses) 和一个新列total,它等于SUM(profit)+SUM(bonus)+SUM(expenses)

附言。重新运行SUM 的查询不是一个选项,因为我已经有了结果。

提前致谢!

【问题讨论】:

  • 视图是数据库中的一个对象。 CTE 仅在单个查询期间存在。它们看起来非常不同。你能提供一个在它们之间进行选择的例子吗?
  • 您正在处理多少数据? CTE 广泛使用 TempDb,如果您的 TempDb 配置不正确或您的 CTE 正在处理大量行,那么这不是最佳选择。处理大量数据时选择查看,处理少量数据时选择 CTE。当您需要递归时,您也可以选择 CTE。就是这样!
  • 您好,感谢您的回复。查看更新的问题
  • @BlackM 检查我的更新答案。

标签: sql sql-server common-table-expression sql-view


【解决方案1】:

视图可以被索引,但 CTE 不能。所以这是很重要的一点。

CTE 在tree hierarchyi.e 上表现出色。递归

此外,在处理复杂查询时考虑视图。视图是数据库上的物理对象(但不物理存储数据)并且可以用于多个查询,因此提供了灵活性和集中的方法。另一方面,CTE 是临时的,将在使用时创建;这就是为什么它们被称为inline view

更新

根据您更新的问题,视图将是正确的选择。在 CTE 中处理 350 万行将在 TempDb 上产生额外的开销,这最终会降低 SQL Server 的性能。请记住,CTE 是一次性视图,因此不存储任何统计信息,您也不能创建索引。它就像一个子查询。

【讨论】:

  • “与视图相比,CTE 不能很好地处理大量数据”这不是真的。除非视图被索引,否则 CTE 和视图之间没有区别。
  • 但是我可以添加column1+column2 as column3 并在查询中显示它吗?
  • @MikaelEriksson 是的,但是在我对大量数据的测试中[递归],我发现 tempdb 的使用率很高,因此性能很低。但是,我仍然相信您的评论是正确的,我正在修改我的答案。
  • @BlackM 您可以在视图中添加计算列,也可以在视图中创建 CTE。
【解决方案2】:

计划优化器对两者的解释完全相同。这只是另一回事。

视图可以单独使用。它可以将复杂的语句封装成更简单的查询。

CTE 主要用于编写更简洁的代码,例如在过程/视图中具有较少冗余。您也可以将 CTE 用于递归查询,这是一个非常棒且强大的功能!

我希望这有助于澄清事情。

【讨论】:

    【解决方案3】:

    选择 CTE 的原因之一:如果您在做分层查询,请使用 CTE。 CTE 可以递归调用。视图不能递归调用。

    【讨论】:

      【解决方案4】:

      CTE 仅在查询运行时存在于内存中。查询运行后,CTE 被丢弃;除非我们再次定义它,否则它不能用于下一个 SQL 查询。尽管如此,同一个 CTE 可能会在主查询和任何子查询中被多次引用。

      视图是存储的 SQL 查询,每次您在另一个查询中引用它时都会执行该查询。请注意,视图不存储特定查询的输出 - 它存储查询本身。

      关于 SQL 视图要记住的关键是,与 CTE 相比,视图是数据库中的物理对象,并且存储在磁盘上。但是,视图只存储查询,而不存储查询返回的数据。每次您在查询中引用视图时都会计算数据。

      【讨论】:

        【解决方案5】:

        再添加一个注意事项:权限。

        • 创建和使用视图需要CREATE 权限,您可能已被授予也可能未被授予。
        • 如果您已被授予权限,您可能会发现自己与其他拥有类似权限并希望创建或更改同名视图的人发生命名冲突。
        • 解决命名冲突的最简单方法是创建额外的架构(命名空间)

        DB管理员可能对上述情况并不认同,所以你可能一开始就无法创建视图。

        在这种情况下,您可以将 CTE 视为一次性视图,它不需要您已经拥有运行 SELECT 查询的更多权限。

        我经常使用 CTE 来创建独立且不需要额外维护的东西,尤其是对于示例代码。

        【讨论】:

          猜你喜欢
          • 2012-08-05
          • 2021-01-17
          • 1970-01-01
          • 1970-01-01
          • 2010-12-24
          • 1970-01-01
          • 1970-01-01
          • 2021-03-31
          • 1970-01-01
          相关资源
          最近更新 更多