2015-11-05 7 views
2

У меня есть запрос SQL, в котором мы выбираем список продуктов, но также необходимо запросить таблицу заказов, чтобы узнать, сколько было продано. Есть ли более эффективный способ получить номер Sold sum без subQuery?Есть ли лучший, более оптимизированный способ выполнения этого SQL-запроса?

SELECT tProducts.ID as ID, 
tProducts.Name, 
tProducts.Description, 
Highlights=Replace(Replace(tProducts.Highlights, '##productdeliverydate##', convert(varchar, @ProjectReleaseDt, 101)),'##productltdedition##', @productltdedition), 
tProducts.isLocked as isLocked, 
tProducts.isVisible as isVisible, 
tProducts.ImageID as ImageID, 
tProducts.ShippingYN as ShippingYN, 
tProducts.LastDateUpdate as LastDateUpdate, 
tProducts.BaseUnitPrice as Price, 
    FileExtension = case tProjectImages.FileExtention 
    WHEN tProjectImages.FileExtention then tProjectImages.FileExtention 
    ELSE '.none' 
    END, 
    @ImagePath as ImagePath, 
    @ImageServerPath as ExternalServerPath, 
    @ThumbExt as ThumbnailExtension,  
    tProducts.SalesContainerTypeID, 
    tProducts.ListOrder, 
    tProducts.isParticipantListed, 
    tProducts.LimitQuantity, 
    tPRoducts.isFeature, 
    numbersold=(SELECT sum(quantity) 
        from tOrderDetails 
        JOIN tOrders 
        on tORders.OrderID=tORderDetails.ORderID 
       where productID=tProducts.ID 
        and tOrders.isTestOrder=0), 
FROM tProducts 
LEFT JOIN tProjectImages ON tProducts.ImageID = tProjectImages.ID 
WHERE tProducts.ProjectID = @projectID 
and tProducts.isVisible=1 
and tProducts.SalesContainerTypeID = 6 
and [email protected] 
ORDER BY tProducts.BaseUnitPrice ASC 

ответ

2

Если у вас возникли проблемы с производительностью, то, возможно, индексы бы помочь.

Лучшие индексы для подзапроса: tOrderDetails(productid, orderid, quantity) и tOrder(orderid, isTestOrder).

Лучшие индексы для внешнего запроса: tProducts(ProjectId, isVisibleId, SalesContainerTypeID, langID, BaseUnitPrice, ImageID) и tProjectImages(Id).

+3

Отмечено как ответ. Предлагаемые индексы были на самом деле лучшим решением, и исходный подзапрос кажется наиболее оптимальным – redoc

1

Я не уверен, будет ли он более эффективным (вы хотите проверить план выполнения). Но вот альтернативная версия с outer join к подзапросу:

SELECT ... 
    numbersold=t.qty, 
FROM tProducts 
    LEFT JOIN tProjectImages ON tProducts.ImageID = tProjectImages.ID 
    LEFT JOIN (
     SELECT sum(quantity) qty, productID 
     FROM tOrderDetails 
      JOIN tOrders on tORders.OrderID =tORderDetails.ORderID 
     GROUP BY productID 
    ) t ON t.productID=tProducts.ID and tOrders.isTestOrder=0 
WHERE tProducts.ProjectID = @projectID and 
    tProducts.isVisible=1 and 
    tProducts.SalesContainerTypeID = 6 and 
    [email protected] 
ORDER BY tProducts.BaseUnitPrice ASC 
+0

Исходный запрос, вероятно, более эффективен. Этот запрос объединяет все детали заказа и заказы. Внешний запрос, вероятно, ограничивает данные только несколькими заказами, основанными на всех ограничениях в предложении 'where'. Коррелированный подзапрос требует только необходимых вычислений. –

+0

@sgeddes - Спасибо, я попробую. Гордон - К сожалению, наверное. У меня есть отвращение к подзапросам :) – redoc

+0

@GordonLinoff - Спасибо за информацию. Я не был уверен, но задался вопросом, будет ли «внешнее соединение/подзапрос» выполняться только один раз, где коррелированный подзапрос будет выполняться для каждого совпадения. Приятно знать. Как и во всех проблемах с производительностью, я обычно просматриваю план выполнения и соответственно продвигаюсь вперед. Еще раз спасибо. – sgeddes

Смежные вопросы