Итак, 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
Вместо 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
CROSS APPLY
поэтому ваш вопрос не имеет смысла. Пожалуйста, отметьте с базой данных, которую вы действительно используете.