首页 > 解决方案 > Cross-Apply 对更大的数据库不利还是替代品的性能更好?

问题描述

所以 2 个(更多是 3 个)问题,我的查询是编码错误还是经过深思熟虑?(善良,我刚刚发现交叉应用并且相对较新)并且交叉应用甚至是最好的连接方式,或者为什么它很慢?

所以我有一个test_tble大约6600 万条记录的数据库表 () 。然后我Temp_tble创建了一个##,其中有一列称为Ordr_nbrnchar (13))。这基本上是我希望找到的。

test_tble4 列(Ordr_nbr、destination、shelf_no、dte_bought)。

这是我当前的查询,它按我想要的方式工作,但性能似乎很慢。

select ##Temp_tble.Ordr_nbr, test_table1.destination, test_table1.shelf_no,test_table1.dte_bought

         from ##MyTempTable

         cross apply(

         select top 1 test_table.destination,Test_Table.shelf_no,Test_Table.dte_bought 

         from Test_Table

         where ##MyTempTable.Order_nbr = Test_Table.order_nbr

         order by dte_bought desc)test_table1

如果 ##Temp_tble只有 17 个订单要搜索它大约需要 2 分钟。如您所见,我正在尝试获取最新的dte_boughtmax(dte_bought)每个订单中的一些。

在索引方面,我运行了数据库引擎调谐器,它说它针对查询进行了优化,并且我创建了所有相关索引,例如test_tble针对dte_bought desc的聚集索引order_nbr等。

执行计划使用索引扫描(在非集群上)和键查找(在集群上)。

我的最终结果是返回order_nbrs## 中的所有内容MyTempTble以及与该相关的目的地列、shelf_no、dte_boughtorder_nbr但仅返回最近购买的列。

抱歉,如果我解释得很糟糕,我可以提供任何需要的信息,只需询问即可。我不要求只是彻头彻尾的“给我代码”,更多的指导、建议和学习。先感谢您。

更新 我现在尝试了一种左连接,它的工作速度相当快,但仍然不是即时或非常快(大约 30 秒),它也不会只返回最近的 dte_bought,有什么想法吗?请参阅下面的左连接代码。

select a.Order_Nbr,b.Destination,b.LnePos,b.Dte_bought
from ##MyTempTble a

left join Test_Table b
   on a.Order_Nbr = b.Order_Nbr
   where b.Destination is not null

更新 2

尝试使用 max 进行另一个 let 连接dte_bought,效果很好,但只返回order_nbr,其他列为NULL。有什么建议吗?

select a.Order_nbr,b.Destination,b.Shelf_no,b.Dte_Bought

from ##MyTempTable a

left join 
(select * from Test_Table where Dte_bought = (
select max(dte_bought) from Test_Table)
)b on b.Order_nbr = a.Order_nbr


order by Dte_bought asc

公里

标签: mysqlsqldatabasevb.netssms

解决方案


而不是CROSS APPLY()你可以使用INNER JOINwith subquery。检查以下查询:

SELECT
    TempT.Ordr_nbr
   ,TestT.destination
   ,TestT.shelf_no
   ,TestT.dte_bought
FROM ##MyTempTable TempT
INNER JOIN (
            SELECT   T.destination
                    ,T.shelf_no
                    ,T.dte_bought
                    ,ROW_NUMBER() OVER(PARTITION BY T.Order_nbr ORDER BY T.dte_bought DESC) ID
             FROM Test_Table T           
            ) TestT
            ON TestT.Id=1 AND TempT.Order_nbr = TestT.order_nbr

推荐阅读