0

できるだけ効率的に「結合」したいテーブルが 2 つあります。

最初のテーブルには製品コードがあります。このテーブルのすべての列が必要です。

2nd 製品コードごとに複数の行を持つ、同じ製品コードが含まれています。

製品コードが最初のテーブルの行と一致する 2 番目のテーブル行の最小値と最大値を取得する必要があります。

以下は私がこれまでに持っているものです。これは醜く、おそらく非常に不正確で遅いです。これには750k行があるため、2番目のテーブルが問題です!

 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

ちょっと常識外れな提案をするつもりなので、FWIW で受け取ってください。

このクエリを 2 つの部分に分割することをお勧めします。MIN 値と MAX 値だけを計算する部分を ProductCode だけで分離すると (正しく推測した場合)、パフォーマンスが大幅に改善されると思います。ドラッグは、「Selects in the Selects」と一緒に行われます。たとえば、select a,b,c,(select ...)

私は(最終的に)これらの選択を使用して、部門/ブランド/などの集約/カンマ区切りリストを取得していることに気付きました。クエリのその部分だけが(例として)サブ選択として実行された場合、またはビュー (例: product_detail_info_view) に配置すると、遭遇するパフォーマンス ヒットを軽減できる可能性があります。アイデアは、「ネストされた」選択が1回のパスでのみ実行されることです。これを行うと、クエリを次のように表現できます。

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 に答える
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 に答える