Перекрестное применение плохо для большой базы данных или альтернативы работают лучше?

0

Итак, 2 (более 3) вопроса, мой запрос плохо закодирован или продуман? (будьте добры, я только что обнаружил cross apply и относительно новый) и является ли corss-apply даже лучшим видом объединения для использования или почему он медленный?

Итак, у меня есть таблица базы данных (test_tble) около 66 миллионов записей. Затем я создал ## Temp_tble котором есть один столбец с именем Ordr_nbr (nchar (13)). Это в основном те, которые я хочу найти.

У test_tble есть 4 столбца (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_bought или max(dte_bought) каждого ордера.

В терминах индекса я запустил тюнер ядра базы данных, и он говорит, что он оптимизирован для запроса, и у меня есть все относительные индексы, такие как кластерный индекс для test_tble для dte_bought desc, включая order_nbr и т.д.

План выполнения использует сканирование индекса (на non_clustered) и поиск ключа (на кластеризованном).

Мой конечный результат - вернуть все order_nbrs в ## MyTempTble вместе со столбцами назначения, shelf_no, dte_bought относительно этого order_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

Попытка другого let join с max 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

KM

  • 0
    MySQL не поддерживает CROSS APPLY поэтому ваш вопрос не имеет смысла. Пожалуйста, отметьте с базой данных, которую вы действительно используете.
Теги:
database
ssms

1 ответ

1

Вместо CROSS APPLY() вы можете использовать INNER JOIN с 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
  • 0
    Привет, большое спасибо за ответ. Я попробовал ваш внутренний запрос на соединение, и первоначально он выдает ошибку для условия «Где», поэтому я изменил его, чтобы иметь «on TempT.Order_nbr = TestT.order_nbr», а затем «WHERE TestT.Id = 1». К сожалению, это было так же долго, если не дольше. Любые другие предложения? Я даже попробовал это с левым соединением там.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню