0

我有 2 个表我希望尽可能有效地“加入”。

第一个表有一个产品代码,我需要这个表中的所有列。

2nd 包含相同的产品代码,每个产品代码具有多行。

我需要获取产品代码与第一个表匹配的第二个表行的最小值和最大值。

以下是我到目前为止所拥有的,它很丑陋,可能非常不正确和缓慢。第二个表是问题,因为它有 750k 行!

 ALTER PROCEDURE [dbo].[GetProductDescriptions]
(
    @site INT = 0,
    @langid INT = 0
)
AS

select p.* ,
stuff((select ',' + cast(FilterValueID as nvarchar(max))from Product_Filter_Mapping c where c.ProductCode = p.ProductCode AND c.ApplicationID = @site for xml path('')),1,1,'') as FilterIDs,
stuff((select ',' + cast(BrandID as nvarchar(max))from Product_Brand_Mapping d where d.ProductCode = p.ProductCode AND d.ApplicationID = @site for xml path('')),1,1,'') as BrandIDs,
stuff((select '|' + cast(Name as nvarchar(max))from Brands e where e.ID IN (SELECT BrandID FROM Product_Brand_Mapping f WHERE f.ProductCode = p.ProductCode AND f.ApplicationID = @site)  for xml path('')),1,1,'') as BrandNames,
stuff((select ',' + cast(DepartmentID as nvarchar(max))from Product_Department_Mapping e where e.ProductCode = p.ProductCode and e.ApplicationID = @site for xml path('')),1,1,'') as DepartmentIDs,
(select MAX(pr.Sell) from Products pr where pr.ProductCode = p.ProductCode AND pr.ApplicationID = @site) as SellTo, 
(select MAX(pr.WholeSale) from Products pr where pr.ProductCode = p.ProductCode AND pr.ApplicationID = @site) as WasTo
from ProductDescription p WHERE p.ApplicationID = @site AND p.LanguageID = @langid
4

2 回答 2

0
CREATE PROCEDURE [dbo].[GetProductDescriptions3]
(
    @site INT = 0,
    @langid INT = 0
)
AS

select p.*,
stuff((select ',' + cast(FilterValueID as nvarchar(max))from Product_Filter_Mapping c where c.ProductCode = p.ProductCode AND c.ApplicationID = @site for xml path('')),1,1,'') as FilterIDs,
stuff((select ',' + cast(BrandID as nvarchar(max))from Product_Brand_Mapping d where d.ProductCode = p.ProductCode AND d.ApplicationID = @site for xml path('')),1,1,'') as BrandIDs,
stuff((select '|' + cast(Name as nvarchar(max))from Brands e where e.ID IN (SELECT BrandID FROM Product_Brand_Mapping f WHERE f.ProductCode = p.ProductCode AND f.ApplicationID = @site)  for xml path('')),1,1,'') as BrandNames,
stuff((select ',' + cast(DepartmentID as nvarchar(max))from Product_Department_Mapping e where e.ProductCode = p.ProductCode AND e.ApplicationID = @site for xml path('')),1,1,'') as DepartmentIDs,
stuff((select ',' + cast(DepartmentID as nvarchar(max)) + '|' + cast(DisplayOrder as nvarchar(max)) from Product_Department_DisplayOrder g where g.ProductCode = p.ProductCode AND g.ApplicationID = @site for xml path('')),1,1,'') as DisplayOrders,
X.SellFrom,
X.SellTo,
X.WasFrom,
X.WasTo
FROM ProductDescription p
OUTER APPLY (
  SELECT 
    MIN(pr.Sell) as SellFrom,
    MAX(pr.Sell) as SellTo, 
    MIN(pr.Wholesale) as WasFrom, 
    MAX(pr.WholeSale) as WasTo
  FROM Products pr
  WHERE where pr.ProductCode = p.ProductCode AND pr.ApplicationID = @site
  ) X
WHERE p.ApplicationID = @site AND p.LanguageID = @langid
于 2012-09-20T13:38:35.757 回答
0

我要提出一个有点开箱即用的建议,所以请接受 FWIW。

我想我会建议将此查询分为两部分。我相信,如果您仅通过 ProductCode(如果我推断正确的话)将单独计算 MIN 和 MAX 值的部分分开,您会看到性能显着提高。拖动伴随着“选择中的选择”,例如选择a,b,c,(选择...)

我(最终)意识到您正在使用这些选择来获取部门/品牌/等的聚合/逗号分隔列表,我想到如果只有查询的那部分(例如)作为子选择执行或放置在视图中(例如 product_detail_info_view),它可能会减轻他们遇到的性能损失。这个想法是“嵌套”选择仅在一次通过中执行。这样做可以让您将查询表达为更像:

select  a.*,ps.SellFrom,ps.SellTo,ps.WasFrom,ps.WasTo
  from  product_detail_info_view a
  join  (select pr.productcode, min(pr.sell) as SellFrom, max(pr.Sell) as SellTo,
                min(pr.WholeSale) as WasFrom, max(pr.WholeSale) as WasTo
           group by pr.productcode) as ps
    on  a.productcode=ps.productcode  -- Or should this be a.productID=ps.productID? Not sure
where a.ApplicationID = @site
  and a.LanguageId = @langid

现在,我完全意识到这方面的细节并不完整,例如,对连接字段并不完全确定,但想法就在那里。我经常发现简化查询的最佳方法是查看是否可以将其分解为块,然后将其“重新组装”成更有效的部分。我希望这有一定的意义。

于 2012-09-20T14:06:40.230 回答