外部应用与左连接性能


37

我正在使用SQL SERVER 2008 R2

我刚刚在SQL中遇到了APPLY,并且很喜欢它如何解决很多情况下的查询问题,

我使用2个左联接的许多表都得到结果,我能够获得1个外部应用。

我的本地数据库表中有少量数据,并且在部署之后,该代码应该在至少20倍大的数据上运行。

我担心对于大量数据而言,外部应用可能需要比2个左连接条件更长的时间,

任何人都可以说出Apply的工作原理,以及它如何影响非常大的数据的性能。如果可能的话,每个表的大小与n1 ^ 1或n1 ^ 2 ...成比例关系……其中n1是表中的行数1。

这是带有2个左联接的查询

select EC.*,DPD.* from Table1 eC left join
  (
   select member_id,parent_gid,child_gid,LOB,group_gid,MAX(table2_sid) mdsid from Table2
   group by member_id,parent_gid,child_gid,LOB,group_gid

  ) DPD2 on DPD2.parent_gid = Ec.parent_gid
        AND DPD2.child_gid = EC.child_gid
        AND DPD2.member_id = EC.member_id
        AND DPD2.LOB = EC.default_lob
        AND DPD2.group_gid = EC.group_gid
  left join
  Table2 dpd on dpd.parent_gid = dpd2.parent_gid 
            and dpd.child_gid = dpd2.child_gid
            and dpd.member_id = dpd2.member_id 
            and dpd.group_gid = dpd2.group_gid 
            and dpd.LOB = dpd2.LOB
            and dpd.table2_sid = dpd2.mdsid

这是带有外部应用的查询

select * from Table1 ec   
OUTER APPLY (
      select top 1 grace_begin_date,retroactive_begin_date,Isretroactive
                    from Table2 DPD 
                    where DPD.parent_gid = Ec.parent_gid
                    AND DPD.child_gid = EC.child_gid
                    AND DPD.member_id = EC.member_id
                    AND DPD.LOB = EC.default_lob
                    AND DPD.group_gid = EC.group_gid
                    order by DPD.table2_sid desc
     ) DPD 

Answers:


44

任何人都可以告诉我们应用程序的工作原理以及它如何影响超大型数据的性能

APPLY是一个关联LATERAL JOIN联接(在某些产品和SQL标准的较新版本中称为)。像任何逻辑构造一样,它对性能没有直接影响。原则上,我们应该能够使用任何逻辑上等效的语法编写查询,并且优化程序会将我们的输入转换为完全相同的物理执行计划。

当然,这将要求优化器知道每种可能的转换,并有时间考虑每个转换。这个过程可能需要比当前的宇宙时代更长的时间,因此大多数商业产品都不采用这种方法。因此,尽管很难做出关于哪个更好以及为什么更好的一般性陈述,但是查询语法可以而且经常确实会影响最终性能。

特定形式的OUTER APPLY ( SELECT TOP ... )极有可能在SQL Server的当前版本中导致相关的嵌套循环联接,因为优化器不包含将这种模式转换为等效模式的逻辑JOIN。如果外部输入很大,而内部输入没有索引,或者所需的页面尚未在内存中,则相关的嵌套循环联接可能无法很好地执行。另外,优化器成本模型的特定元素意味着相关的嵌套循环联接比语义上相同的可能性更不可能JOIN产生并行执行计划。

我能够通过单个左联接和row_number()进行相同的查询

在一般情况下,这可能会更好,也可能不会更好。您将需要对具有代表性数据的这两种选择进行性能测试。在LEFT JOINROW_NUMBER肯定有潜力成为更有效,但它取决于所选择的精确查询计划形状。影响此方法效率的主要因素是索引的可用性,以覆盖所需的列并提供PARTITION BYand ORDER BY子句所需的顺序。第二个因素是表格的大小。如果查询涉及相关表的较小部分,则高效且索引良好的索引APPLY可以胜过ROW_NUMBER具有最佳索引的索引。需要测试。


2

第一个查询只能通过对sql服务器的一个请求并行运行。它获取所有记录,并根据过滤条件提供输出。

但是如果是第二个,它将逐行运行,并且每行将扫描Table2并将其附加到结果中。

如果外部查询的记录较少,则第二个记录更好(外部申请)。但是,如果第一个查询可能获得更多数据,那么您应该使用第一个。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.