Ускорить запрос Cross Apply

У меня есть запрос, использующий Cross Apply. Мне нужно выполнить запрос для нескольких [Quote Id]. Вот мой исходный запрос:

SELECT distinct
       [Reports].[Quote_Header_Details_vw].[Quote_Id]    
      ,[Reports].[Quote_Header_Details_vw].[Quote_Created]
      ,[Reports].[Quote_Header_Details_vw].[Com_Product]
      ,[Reports].[Quote_Header_Details_vw].[Ene_Product]
      ,b.[Completed]
      ,b.[Description]
FROM [Reports].[Quote_Header_Details_vw]
   CROSS APPLY (SELECT Top 1
                         Core.Job.[Completed]
                        ,Core.Job.[Description]
FROM Core.Job
WHERE [Quote_Header_Details_vw].[Quote_Created]>=Core.Job.[Completed] 
And Core.Job.[Description] like '%'+[Reports].[Quote_Header_Details_vw].[Ene_Product]
Order by Core.Job.[Completed] DESC) AS b

Я понимаю, что много времени тратится на выполнение операции Top 1 в операторе Cross Apply. В настоящее время выполнение запроса для одного идентификатора предложения занимает более 40 секунд, и по мере роста таблицы Core.Job запрос будет становиться все медленнее и медленнее. Поэтому для меня это неприемлемое решение.

Есть ли более быстрый и лучший способ сделать это? Большое спасибо. Обратите внимание, что между таблицами [Quote_Header_Details_vw] и [Core.Job] нет никакой связи, т.е. нельзя их объединить.


person C.C    schedule 18.03.2016    source источник
comment
Возможный дубликат разницы в производительности CROSS APPLY   -  person Ashraf Sada    schedule 18.03.2016
comment
@a_horse_with_no_name Понятно, спасибо.   -  person C.C    schedule 18.03.2016
comment
@Ашраф Абусада Спасибо. Не то же самое, две таблицы вообще не связаны друг с другом.   -  person C.C    schedule 18.03.2016
comment
Вы настроили каждый из двух запросов? Используйте Sql Server Profiler, чтобы увидеть, можете ли вы сделать это в первую очередь, если они оптимизированы (хорошие индексы и т. д.), то посмотрите на CROSS APPLY   -  person Igor    schedule 18.03.2016
comment
Ваш фильтр Core.Job.[Description] типа '%'+[Reports].[Quote_Header_Details_vw].[Ene_Product] не подлежит анализу и будет выполнять полное сканирование таблицы для каждой отдельной записи, чтобы вернуть одну строку.   -  person Steve Mangiameli    schedule 18.03.2016
comment
Спасибо. Я понимаю фильтр: ГДЕ [Quote_Header_Details_vw].[Quote_Created]›=Core.Job.[Completed] And Core.Job.[Description] как '%'+[Reports].[Quote_Header_Details_vw].[Ene_Product] не подлежит анализу ', вызывает долгое время. Хотите знать, как решить это относительно простым способом, если он есть :-)   -  person C.C    schedule 18.03.2016
comment
Просто выберите эти два значения в переменных   -  person paparazzo    schedule 18.03.2016
comment
Лучший способ исправить это — исправить вашу модель данных. В любое время, когда вам нужно, например, с таким подстановочным знаком, ваша модель данных безвозвратно сломана и должна быть исправлена. У вас всегда будут медленные запросы и возможность получения неточных результатов, если вы не исправите это. Было бы легче увидеть, есть ли способ помочь вам, если вы разместите некоторые образцы данных в таблицах, о которых вы говорите, а затем ожидаемые результаты. Поскольку вы присоединяетесь к представлению, возможно, все это можно улучшить, улучшив также представление.   -  person HLGEM    schedule 22.03.2016
comment
@HLGEM Я согласен. К сожалению, я не могу изменить конфигурацию данных (навыки SQL недостаточны для этого, даже если я могу что-то сделать с данными) :-P Спасибо.   -  person C.C    schedule 24.03.2016


Ответы (1)


просто поместите их в переменные, а затем используйте переменную в выборе

declare @dd1 varchar(20);
declare @dd2 varchar(20);
select top (1) @dd1 = [name],  @dd2 = [dispName]
from [table]
order by [name] desc; 
select @dd1, @dd2;

ОП нужна конкретика

declare @dd1 varchar(20);
declare @dd2 varchar(20);

SELECT Top (1)
       @dd1 = Core.Job.[Completed]
     , @dd2 = Core.Job.[Description]
FROM Core.Job
WHERE [Quote_Header_Details_vw].[Quote_Created] >= Core.Job.[Completed] 
And Core.Job.[Description] like '%'+[Reports].[Quote_Header_Details_vw].[Ene_Product]
Order by Core.Job.[Completed] DESC;


SELECT distinct
       [Reports].[Quote_Header_Details_vw].[Quote_Id]    
      ,[Reports].[Quote_Header_Details_vw].[Quote_Created]
      ,[Reports].[Quote_Header_Details_vw].[Com_Product]
      ,[Reports].[Quote_Header_Details_vw].[Ene_Product]
      ,@dd1 as [Completed]
      ,@dd2 as [Description]
FROM [Reports].[Quote_Header_Details_vw];

или попробуй

select * from 
(
SELECT r.[Quote_Id]    
      ,r.[Quote_Created]
      ,r.[Com_Product]
      ,r.[Ene_Product]
      ,b.[Completed]
      ,b.[Description] 
      ,row_number() over (partition by r.[Quote_Id] order by b.[Completed] desc) as rn
FROM [Reports].[Quote_Header_Details_vw] r
join Core.Job b
       on r.[Quote_Created] >= b.Job.[Completed] 
      And b.[Description] like '%'+r.[Ene_Product]
) tt
where tt.rn = 1
person paparazzo    schedule 18.03.2016
comment
Большое спасибо. Но я не понимаю логики этого. Таблица b упорядочена по [Completed] DESC, а не упорядочена по [name] DESC. Нужно ли также помещать [Quote_Created] и [Completed] в переменные? - person C.C; 22.03.2016
comment
Поместите вывод CROSS APPLY в переменные и устраните перекрестное применение. Это всего лишь пример синтаксиса для назначения переменных. - person paparazzo; 22.03.2016
comment
Это не даст правильных значений - их нужно оценивать для каждой строки, следовательно, применять. - person Gareth Lyons; 22.03.2016
comment
@GarethLyons Вы правы. Я взял Обратите внимание, что между таблицами [Quote_Header_Details_vw] и [Core.Job] нет никакой связи, что означает, что на самом деле не было никакой связи. Спасибо за отрицательный голос, чтобы укрепить точку. - person paparazzo; 22.03.2016
comment
Большое спасибо вам обоим. Извините, если я недостаточно ясно изложил свою мысль. Для каждого [Quote_Id] из таблицы [Reports].[Quote_Header_Details_vw] я хотел найти первое [Description] в таблице b. Чтобы создать b, я применяю два фильтра, которые используют информацию из каждого [Quote_Header_Details_vw].[Quote_Id]. Это означает, что для каждой строки [Quote_Id] таблица b будет разной. @Папарацци, я буду следовать твоей логике, чтобы проверить. Спасибо. - person C.C; 24.03.2016