CROSS APPLY issue - filtering a many-to-one relationship
我发现了一个关于MS SQL Server如何处理
我正在使用的数据库具有以下模式的定价系统:
Service -> Price Model <- Price Component ('->' indicates a Foreign Key pointing to the table)
有些价格模型有"阶梯式定价",即当金额参数达到不同的阈值时,价格会上涨(1-3个单位为价格A,4-8个单位为价格B等)。
我遇到的问题是[price model id]上的[service]和[price component]之间的EDOCX1[1]正在生成重复的行,因为我实际上并没有使用price component中的price,只是表中的另一个字段对于每个[price component]行都是相同的。
1 2 3 4 | SELECT * FROM [Service] s INNER JOIN [Price Component] pc ON s.[Price Model Id] = pc.[Price Model Id] |
这个问题的逻辑解决方法是用一个执行此操作的
1 2 3 4 5 6 | SELECT * FROM [Service] s CROSS APPLY (SELECT TOP 1 * FROM [Price Component] pc WHERE s.[Price Model Id] = pc.[Price Model Id] ) AS pc |
问题是,效率在其他一些似乎与这一变化无关的连接中被彻底摧毁。看看执行计划,过去需要2.3个周期的连接现在需要480万个周期。
我试着在原始查询中添加一个
1 2 3 4 5 6 | SELECT * FROM [Service] s CROSS APPLY (SELECT DISTINCT pc.moneyUnitId FROM [Price Component] pc WHERE s.[Price Model Id] = pc.[Price Model Id] ) AS pc |
奇怪的是,将
有没有人对导致
更新
因此,在阅读了更多关于如何解释执行计划的内容之后,我学到了以下几点:
原始查询(使用
INNER JOIN s)是一系列嵌套循环从你提供的过滤数据开始。漂亮的快餐店只要筛选器位于索引字段上,则响应时间为。修改后的查询(使用
CROSS APPLY 是一个较长的哈希序列匹配,并将你给它的每一张桌子连接起来,除了那些筛选,然后最后应用筛选。总是比死亡慢。使用修改后的查询(使用
OUTER APPLY 时),与原始,但不排除与WHERE子句。和原版一样快。
所以问题是:为什么一个
为什么不:
1 2 | select t1.colA, t3.colX from table1 t1 inner join (select distinct t2.t1FK, t2.colX from table2 t2) t3 on t1.ID = t3.t1FK |
如果表中只有一个字段和一个字段,那么您是否考虑过使用group by和max()筛选记录?
1 2 3 4 | select a.field1, a.field2, max(b.field3) from table1 a join table2 b on a.someid = b.someid group by a.field1, a.field2 |
如果