Перекрестное применение плохо для большой базы данных или альтернативы работают лучше? - PullRequest
0 голосов
/ 31 января 2019

так 2 (более 3) вопроса, мой запрос просто плохо закодирован или продуман?(будьте добры, я только что обнаружил перекрестное применение и относительно новое) и является ли применение 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 вместе со столбцами destination, 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

Попытка еще одного соединения с максимальным значением 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

КМ

1 Ответ

0 голосов
/ 31 января 2019

Вместо 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...