为什么此Advantage Database查询需要这么长时间?

时间:2018-12-04 19:18:55

标签: advantage-database-server

首先,在Orders.Order_Number,OrderDet.Order_Number和OrderDet.PatID上有索引。还有其他索引,但是这些索引在我看来很相关。

在我完成的测试中,此查询需要20到114 的时间来执行。

Update O
   SET O.BenefitID = 1,
       O.LastChangedBy = 'RH Test' 
   FROM Orders O
   JOIN OrderDet od ON od.Order_Number = O.Order_Number
   WHERE
         Od.PatID = 703007
         and Od.Status IN ('2', '7', '50', '51', '52', '78', '82');

如果我改为这样做,我得到的时间不到60毫秒:

SELECT ODetailID, Order_Number INTO #OrdNum FROM OrderDet 
   WHERE PatID = 703007
   AND Status IN ('2', '7', '50', '51', '52', '78', '82');  
Update Orders
   SET BenefitID = 1,
       LastChangedBy = 'RH Test' 
   WHERE Order_Number in (SELECT Order_Number from #OrdNum);        

   DROP TABLE #OrdNum;

有人可以告诉我为什么将OrderDet表连接到Orders时我的查询需要这么长时间吗?对我来说,加入这么长时间是没有道理的。如果我根据order_number在任一表上进行选择,则会得到200ms以下的响应。如果我使用PatID在OrderDet上选择,我将得到40ms以下的响应。通过PatId选择订单需要更长的时间-1-2秒,但该列上没有索引。我不明白为什么使用联接会花费多达114秒的时间,因为联接位于两个表中都已索引的列上。非常感谢您对此有任何帮助。

1 个答案:

答案 0 :(得分:2)

此行为的原因是因为使用联接执行UPDATE操作时,正在更新的表被固定为嵌套循环联接的驱动表。由于“订单”表上没有直接条件,因此“表扫描”是唯一的选择。

在具有两个表的内部联接的SELECT查询中,可以将这些表切换为将具有更多限制结果的表作为驱动程序放置。这样可以提高性能。

使用临时表的另一种方法是使用子查询,该子查询无论如何都是更标准的:

Update Orders
   SET BenefitID = 1,
       LastChangedBy = 'RH Test' 
   WHERE Order_Number in 
       (SELECT Order_Number 
        FROM OrderDet 
        WHERE PatID = 703007
        AND Status IN ('2', '7', '50', '51', '52', '78', '82'));