[英]SQL recursive hierarchy very slow
因此,我剛完成一項優化SQL查詢的任務,該SQL查詢構建了產品,內部產品,制造操作,操作細節和項目(制造產品所需)的層次結構樹。 該查詢返回218k行,可以正常工作,但是大約需要15-18秒來構建樹。 是否可以優化該查詢,因此大約需要2-3秒? 如果我將@ProductID添加為該過程的參數並執行
WHERE ProductID = @ProductID
從“產品”表中選擇后,它的運行速度非常快,但是樹卻不完整,因為如果我為其構建樹的產品是內部產品,則其父產品不會顯示在樹中。 將所有這些表加載到C#應用程序並在那里進行所有層次結構構建會更快嗎?
我願意接受所有想法。 下面是有問題的查詢
ALTER PROCEDURE [dbo].[ProductProduct_selectHierarchy_v2]
WITH EXECUTE AS CALLER
AS
BEGIN
WITH ProductProductHierarchy (
ProductID
,ItemProductID
,LEVEL
,UniqueID
,ParentID
,RowType
,ProductDetailID
,ProductProductDetailBindID
,ManufactoryOperationID
,ItemID
)
AS (
-- Anchor member definition
SELECT dbo.Product.ProductID AS ProductID
,Product.ProductID AS ItemProductID
,0 AS LEVEL
,Cast(cast(Product.ProductID AS NVARCHAR(40)) + '' AS NVARCHAR(50)) AS UniqueID
,cast('' AS NVARCHAR(50)) AS ParentID
,1 AS RowType
,NULL AS ProductDetailID
,NULL AS ProductProductDetailBindID
,NULL AS ManufactoryOperationID
,NULL AS ItemID
FROM dbo.Product
UNION ALL
-- Recursive member definition
SELECT e.ProductID
,e.ItemProductID
,LEVEL + 1
,Cast(Cast(d.UniqueID AS NVARCHAR(40)) + '_' + cast((e.ItemProductID) AS NVARCHAR(10)) AS NVARCHAR(50)) AS UniqueID
,Cast(d.UniqueID AS NVARCHAR(50)) AS ParentID
,1 AS RowType
,NULL AS ProductDetailID
,NULL AS ProductProductDetailBindID
,NULL AS ManufactoryOperationID
,NULL AS ItemID
FROM dbo.ProductProduct AS e
INNER JOIN ProductProductHierarchy AS d ON e.ProductID = d.ItemProductID
UNION ALL
SELECT NULL AS ProductID
,NULL
,LEVEL + 1
,Cast(Cast(d.UniqueID AS NVARCHAR(40)) + '_' + cast((e.ProductDetailID) AS NVARCHAR(10)) AS NVARCHAR(50)) AS UniqueID
,Cast(d.UniqueID AS NVARCHAR(50)) AS ParentID
,2 AS RowType
,e.ProductDetailID AS ProductDetailID
,e.ProductProductDetailBindID AS ProductProductDetailBindID
,NULL AS ManufactoryOperationID
,NULL AS ItemID
FROM dbo.ProductProductDetailBind AS e
INNER JOIN ProductProductHierarchy AS d ON e.ProductID = d.ItemProductID
UNION ALL
SELECT NULL AS ProductID
,NULL
,LEVEL + 1
,Cast(Cast(d.UniqueID AS NVARCHAR(40)) + '_' + cast((e.ManufactoryOperationID) AS NVARCHAR(10)) AS NVARCHAR(50)) AS UniqueID
,Cast(d.UniqueID AS NVARCHAR(50)) AS ParentID
,3 AS RowType
,NULL AS ProductDetailID
,NULL AS ProductProductDetailBindID
,e.ManufactoryOperationID AS ManufactoryOperationID
,NULL AS ItemID
FROM dbo.ProductDetailOperation AS e
INNER JOIN ProductProductHierarchy AS d ON e.ProductProductDetailBindID = d.ProductProductDetailBindID
UNION ALL
SELECT NULL AS ProductID
,NULL
,LEVEL + 1
,Cast(Cast(d.UniqueID AS NVARCHAR(40)) + '_' + cast((e.ItemID) AS NVARCHAR(10)) AS NVARCHAR(50)) AS UniqueID
,Cast(d.UniqueID AS NVARCHAR(50)) AS ParentID
,4 AS RowType
,NULL AS ProductDetailID
,NULL AS ProductProductDetailBindID
,NULL AS ManufactoryOperationID
,e.ItemID AS ItemID
FROM dbo.ProductItem AS e
INNER JOIN ProductProductHierarchy AS d ON e.ProductID = d.ItemProductID
)
-- Statement that executes the CTE
SELECT CASE
WHEN RowType = 1
THEN ProductName + '<' + ProductCode + '>'
WHEN RowType = 2
THEN ProductDetail.ProductDetailName
WHEN RowType = 3
THEN ManufactoryOperation.ManufactoryOperationName
ELSE Item.ItemName
END AS ProductName
,UniqueID
,ProductProductHierarchy.ParentID
,Product.ProductID
,RowType
FROM ProductProductHierarchy
LEFT OUTER JOIN Product ON Product.ProductID = ProductProductHierarchy.ItemProductID
AND RowType = 1
LEFT OUTER JOIN ProductDetail ON ProductDetail.ProductDetailID = ProductProductHierarchy.ProductDetailID
AND RowType = 2
LEFT OUTER JOIN ManufactoryOperation ON ManufactoryOperation.ManufactoryOperationID = ProductProductHierarchy.ManufactoryOperationID
AND RowType = 3
LEFT OUTER JOIN Item ON Item.ItemID = ProductProductHierarchy.ItemID
AND RowType = 4
OPTION (MAXRECURSION 0)
結束
看來您正在有效地構建一組異構行,但我通常會盡量避免這樣做。 如果需要,可以使用遞歸獲取產品樹,然后將操作,項目等作為單獨的結果集。 像這樣混合行類型很可能會引起麻煩(而不僅僅是性能問題)。
在不了解應用程序的全部功能的情況下,我無法說出應該從數據庫中檢索這些項目的最佳方法,但是我肯定會從那里開始作為一個可能的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.