Sql 堆叠联接的性能较差

Sql 堆叠联接的性能较差,sql,Sql,我不确定我能否提供足够的细节来回答问题,但我的公司在使用较旧的mssql视图时遇到了性能问题。我已经把范围缩小到了右边的外部连接,但是我不熟悉连接的结构,下面的连接没有一个“开”,就像下面的代码片段一样 我如何编写下面的联接来提高性能,或者使用Field1=field2格式的联接表名的更简单格式 您最后的内部联接有许多ON语句。根据问答,这种语法相当于嵌套子查询。这是我见过的最糟糕的查询之一。由于我无法理解在没有基础数据的情况下它应该如何工作,因此我建议您这样做 首先找到一个好的示例loan,并

我不确定我能否提供足够的细节来回答问题,但我的公司在使用较旧的mssql视图时遇到了性能问题。我已经把范围缩小到了右边的外部连接,但是我不熟悉连接的结构,下面的连接没有一个“开”,就像下面的代码片段一样

我如何编写下面的联接来提高性能,或者使用Field1=field2格式的联接表名的更简单格式


您最后的
内部联接
有许多
ON
语句。根据问答,这种语法相当于嵌套子查询。

这是我见过的最糟糕的查询之一。由于我无法理解在没有基础数据的情况下它应该如何工作,因此我建议您这样做

首先找到一个好的示例loan,并针对该视图编写一个查询,以返回loan_id=。。。现在您有了一个数据集,您可以根据它检查更改,这可能比它返回的数百万条记录更容易。确保这些结果是有意义的(tbl_对象的右连接让我感到困扰,因为返回所有对象记录是没有意义的)

现在开始用您认为应该是第一个表的内容编写查询(我建议loan是第一个表,如果不是,那么第一个表是Object left Join to loan)和loan id的where子句。 检查您的结果,您是否获得了与添加where子句的view查询相同的贷款信息

然后一次添加一个连接,查看它如何影响查询,以及结果是否偏离轨道。一旦您找到了一个查询,该查询在所有添加的表中都给出了相同的结果,那么您可以尝试检查其他几个贷款ID。一旦这些都签出了,然后运行不带where子句的整个查询,并对照查看结果进行检查(如果是一个大数字,您可能需要查看记录计数是否匹配并进行目视检查(在这两个方面都使用order by,以确保结果的顺序相同)。在此过程中,请尝试仅使用左连接,而不是右连接和左连接的组合(可以单独使用内部连接)。 在复杂的查询中,我习惯先做所有的内部连接,然后做左连接。我从不在生产代码中使用右连接。 现在,您已经准备好进行性能调整

我猜对对象的右连接会导致一个问题,因为它返回整个表,而该表名和对同一个表的其他连接的性质使我相信他可能想要左连接。在不知道数据含义的情况下,很难确定。因此,首先,如果一个表返回了太多记录一个ID,然后考虑实际问题是,随着表的增长,返回太多的记录已经成为问题。

也可以考虑经常使用TEH视图并用代码替换它以获得相同的结果。视图调用视图是一种很差的技术,通常会导致性能问题。通常,其他视图顶部的视图调用相同的表,因此当您不需要的时候,您会多次加入它们。

根据您拥有的数据库后端,检查您的解释计划或执行计划。对此的分析应显示您可能缺少索引的位置

还要确保查询中的每个表都是必需的。当您连接到视图时尤其如此。视图可以连接到其他12个表,但您只需要其中一个表中的数据,并且它可以连接到您的一个表。确保您没有使用select*,而只返回视图实际需要的字段。您有内部连接,因此,通过定义中,选择*将返回不需要的字段

如果你选择的一部分TEHVIEW有一个不同的地方,那么考虑一下如果你可以删除多个记录,你需要通过改变一个派生表或添加一个WHERE子句来区分它。要知道是什么导致了倍数,你可能需要临时使用SELECT*来查看所有的列并找出哪个不是UNIQUE和I。这是问题的根源


整个过程并不容易,也不有趣。只要慢慢来,仔细而有条理地工作,你就会到达那里,最终得到一个可以理解和维护的查询。

a
RIGHT-OUTER-JOIN
LEFT-OUTER-JOIN
需要一个
ON
子句,就像常规的
JOIN
(或者被联接的表之间的关系必须出现在WHERE子句中,这被认为是不好的形式)。此外,外部联接的工作方式与内部联接不同,因此如果您不确定它们是如何工作的,最好在切换到直接的
联接之前了解它们(这是
内部联接的缩写)。我怀疑在您的
WHERE
子句中,您可以找到正在联接的表之间的关系,此处省略了
上的
。在视图中,您确实有两个选项,将查询重写为使用子查询联接,而不是联接到完整的表,或者确保适当的索引已就位(索引视图或基础表)。此视图上没有Where子句。以前的DBA在许多视图(和存储的进程)上广泛使用此堆叠连接系统。我以前从未见过它。我总是看到每个“连接”都有一个“开”,所以我有点被难住了。我很确定转移到派生查询是一条路,但我没有得到这个堆叠连接的东西。@stevenackley,因为这个可怕的查询调用另一个视图(一个非常糟糕的实践本身),所以这个视图不可能是可索引的(至少在SQL Server中是不可能的)@HLGEM视图本身是不可索引的,但底层的表是它只是连接语法的一种变体(100%标准SQL):
从b.id=c.id的连接到a.id=c.id的连接到b.id=c.id的连接与从b.id=c.id的连接到a.id=c.id的连接完全相同
  FROM    dbo.tblObject AS tblObject_2
            JOIN dbo.tblProspectB2B PB ON PB.Object_ID = tblObject_2.Object_ID
            RIGHT OUTER JOIN dbo.tblProspectB2B_CoordinatorStatus
            RIGHT OUTER JOIN dbo.tblObject
            INNER JOIN dbo.vwDomain_Hierarchy
            INNER JOIN dbo.tblContactUser
            INNER JOIN dbo.tblProcessingFile WITH ( NOLOCK )
            LEFT OUTER JOIN dbo.enumRetentionRealization AS RR ON RR.RetentionRealizationID = dbo.tblProcessingFile.RetentionLeadTypeID
            INNER JOIN dbo.tblLoan
            INNER JOIN dbo.tblObject AS tblObject_1 WITH ( NOLOCK ) ON dbo.tblLoan.Object_ID = tblObject_1.Object_ID ON dbo.tblProcessingFile.Loan_ID = dbo.tblLoan.Object_ID ON dbo.tblContactUser.Object_ID = dbo.tblLoan.ContactOwnerID ON dbo.vwDomain_Hierarchy.Object_ID = tblObject_1.Domain_ID ON dbo.tblObject.Object_ID = dbo.tblLoan.ContactOwnerID ON   dbo.tblProspectB2B_CoordinatorStatus.Object_ID =   dbo.tblLoan.ReferralSourceContactID ON tblObject_2.Object_ID =       dbo.tblLoan.ReferralSourceContactID