【问题标题】:SQL joins with viewsSQL 与视图连接
【发布时间】:2014-12-05 16:54:22
【问题描述】:

我有一个视图,它现在将其他两个视图与一些额外的表连接起来。 速度很慢。

我的经验告诉我这是因为默认情况下视图没有被索引。我尝试为它们中的每一个创建一个索引,但这是不可能的,因为它们具有自连接或内部查询。

我的问题是: 在我看来,一般不建议加入视图。所以,简而言之,有没有办法将代码从一个视图重用到另一个视图?示例:视图 A 计算百分比,视图 B 使用视图 A 中的百分比以及来自其他表/视图的其他信息来计算其他内容。最好的方法是什么?您真的必须将代码从视图 A 复制到视图 B,以便它使用原始表的索引吗?

视图(简化视图,显示问题):

查看A(计算百分比):

SELECT     dbo.tblPopAgeGrp.RevID, dbo.tblPopAgeGrp.VarID, dbo.tblPopAgeGrp.LocID, 
                      dbo.tblPopAgeGrp.TimeID, dbo.tblPopAgeGrp.AgeID, tPAGT.AgeID AS AgeTotal, 
                      100 * dbo.tblPopAgeGrp.PopMale / tPAGT.PopMale AS PopMalePerc, 
                      100 * dbo.tblPopAgeGrp.PopFemale / tPAGT.PopFemale AS PopFemalePerc, 
                      100 * dbo.tblPopAgeGrp.PopTotal / tPAGT.PopTotal AS PopTotalPerc
FROM         dbo.tblPopAgeGrp
INNER JOIN   dbo.tblPopAgeGrp tPAGT
        ON dbo.tblPopAgeGrp.GroupID = tPAGT.GroupID
        AND dbo.tblPopAgeGrp.AgeID = 700

查看A本身,因为有这么多的记录,需要很长时间才能执行。但是,在视图 B 中,记录是根据 VersionID 过滤的。

视图 B(从视图 A 获取百分比以及来自另一个视图的附加信息):

SELECT     vPAGP.VersionID, 
           vPAGP.LocationID AS LocID, 
           vPAGP.PopTotalPerc  AS pPopTot,
           vPAGP.PopMalePerc   AS pMale,
           vPAGP.PopFemalePerc AS pFemale,
           vPAGPSR.PopMaleSexRatio    AS SexRatio,
           vPAGPSR.PopFemaleSexRatio  AS FemRatio
FROM       dbo.vwA AS vPAGP
INNER JOIN dbo.vwOther AS vPAGPSR
           ON vPAGPSR.GroupID = vPAGP.GroupID
WHERE vPAGP.VersionID=10

执行不带过滤器的视图 A 大约需要 10 分钟。仅对 VersionID=10 执行它,它会在 10 秒内执行。视图 vwOther 执行速度非常快。

谢谢!

【问题讨论】:

  • 我认为这些不是索引视图?它们可以成为索引视图吗? stackoverflow.com/questions/3986366/…
  • 视图应该利用视图中使用的表的底层索引。
  • 我认为查询优化器会足够聪明地使用这些索引,但是如果查询变得太复杂,它就不再起作用了。我会检查解释计划,看看是否有任何索引要添加或更改任何表。

标签: sql sql-server performance join sql-view


【解决方案1】:

当您说“在我看来,通常不建议加入视图”时,您是不正确的。

视图可以与其他视图组合并且性能良好前提是所有 JOINs 都是可优化的并创建了适当的索引并且在视图中完成的任何过滤都是可优化的并创建了适当的索引.

基于其他视图的视图的性能应该与为分解视图而编写的相同查询一样好。如果您需要进一步的帮助,请发布您的问题所涉及的所有视图的定义。

【讨论】:

  • 感谢您的回答!我提供了更多信息来说明我的意思。
  • 关键是:VersionID过滤显然是在整个View A生成之后才应用的,这需要很长时间。如果我在分配了 VersionID 的情况下单独执行视图 A,它将在 10 秒内执行。
  • 再次感谢您的回答。我注意到更改内部连接的顺序并将过滤器移动到 ON 子句而不是 WHERE 子句对性能有重要影响。
猜你喜欢
  • 1970-01-01
  • 2011-02-05
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
  • 1970-01-01
相关资源
最近更新 更多