Почему этот запрос к базе данных Advantage занимает так много времени? - PullRequest
0 голосов
/ 04 декабря 2018

Во-первых, существуют индексы для 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, я получу ответ менее 200 мс.Если я выбираю OrderDet с использованием PatID, я получаю ответ менее 40 мс.Выбор заказов по PatId занимает больше времени - 1-2 секунды, но для этого столбца нет индекса.Я не понимаю, почему это займет до 114 секунд с объединением, так как объединение находится на столбце, который проиндексирован в обеих таблицах.Любая помощь в понимании этого очень ценится.

1 Ответ

0 голосов
/ 11 декабря 2018

Причина такого поведения заключается в том, что при выполнении операции 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'));        
...