我正在使用 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
谁能告诉应用究竟是如何工作的,以及它将如何影响非常大的数据中的性能
APPLY是关联LATERAL JOIN联接(在某些产品和 SQL 标准的较新版本中称为 a )。与任何逻辑结构一样,它对性能没有直接影响。原则上,我们应该能够使用任何逻辑上等价的语法编写查询,并且优化器会将我们的输入转换为完全相同的物理执行计划。
APPLY
LATERAL JOIN
当然,这需要优化器了解每一种可能的转换,并有时间考虑每一种转换。这个过程可能需要比当前宇宙年龄更长的时间,因此大多数商业产品不采用这种方法。因此,查询语法可以并且经常确实对最终性能产生影响,尽管很难就哪个更好以及为什么做出一般性陈述。
的特定形式OUTER APPLY ( SELECT TOP ... )最有可能在当前版本的 SQL Server 中导致相关的嵌套循环连接,因为优化器不包含将此模式转换为等效的JOIN. 如果外部输入很大,而内部输入没有索引,或者需要的页面不在内存中,则相关嵌套循环连接可能无法很好地执行。此外,优化器成本模型的特定元素意味着相关嵌套循环连接不太可能JOIN产生并行执行计划。
OUTER APPLY ( SELECT TOP ... )
JOIN
我能够使用单左连接和 row_number() 进行相同的查询
在一般情况下,这可能会更好,也可能不会更好。您将需要使用代表性数据对两种备选方案进行性能测试。和当然有可能提高效率LEFT JOIN,ROW_NUMBER但这取决于选择的精确查询计划形状。影响这种方法效率的主要因素是索引的可用性,以覆盖所需的列,并提供PARTITION BYandORDER BY子句所需的顺序。第二个因素是桌子的大小。如果查询涉及相关表的相对较小部分,则有效且索引良好的索引APPLY可以胜过具有最佳索引的查询。ROW_NUMBER需要进行测试。
LEFT JOIN
ROW_NUMBER
PARTITION BY
ORDER BY