【问题标题】:. It’s working fine when I pass 10-15 input but taking more than 5 minutes for 30 input. I need to make it work for 100 inputs.当我通过 10-15 个输入但 30 个输入需要超过 5 分钟时,它工作正常。我需要让它适用于 100 个输入
【发布时间】:2017-09-13 21:44:04
【问题描述】:

这是我的问题:

  1. 浏览代码并理解它。
  2. 作为第一个解决方案,对于 30 个输入,查询应在 10 秒内完成
  3. 对于 100 个输入,它也应该具有良好的性能。

我的代码:

/**************************************************
Populating the Array values in table variable
**************************************************/
DECLARE @PUZZLE table(  
   ID int IDENTITY(1,1) NOT NULL,  
   Value int NOT NULL)
/****Sample 1*****/
INSERT INTO @PUZZLE (value)
--SELECT 0 UNION ALL
--SELECT -22 UNION ALL
--SELECT -33 UNION ALL
--SELECT -44 UNION ALL
--SELECT 55 UNION ALL
--SELECT -100 UNION ALL
--SELECT 100 UNION ALL
--SELECT 10 UNION ALL
--SELECT -30 UNION ALL
--SELECT -60 UNION ALL
--SELECT -60 UNION ALL
SELECT -60 UNION ALL
SELECT -10 UNION ALL
SELECT 10 UNION ALL
SELECT 10 UNION ALL
SELECT -10 UNION ALL
SELECT 0 UNION ALL
SELECT -22 UNION ALL
SELECT -33 UNION ALL
SELECT -44 UNION ALL
SELECT 55 UNION ALL
SELECT -100 UNION ALL
SELECT 100 UNION ALL
SELECT 10 UNION ALL
SELECT -30 UNION ALL
SELECT -60 UNION ALL
SELECT -60 UNION ALL
SELECT -60 UNION ALL
SELECT -10 UNION ALL
SELECT 10 UNION ALL
SELECT 10

/**************************************************
Populating possible hierarchy/path
**************************************************/

DECLARE @puzHierarchy table (parentid int, childid int,value int)

INSERT @puzHierarchy (parentid,childid,value)
SELECT *-- INTO #puzHierarchy
FROM (
    SELECT NULL AS ParentId,ID AS ChildId, Value 
    FROM @PUZZLE 
    WHERE ID = (SELECT MIN(ID) FROM @PUZZLE)
    UNION ALL
    SELECT B.Id,C.ID,C.Value
    FROM @PUZZLE B
    JOIN @PUZZLE C
        ON C.ID > B.ID AND C.ID < (B.ID + 7)
) A

--SELECT * FROM @puzHierarchy order by parentid

/*******************************************************
Logic using recursive CTE to get the path with max value
*******************************************************/
;WITH children AS
(

   SELECT ParentId
            ,CAST(ISNULL(CAST(ParentId AS NVARCHAR) + '->' ,'')  + CAST(ChildId AS NVARCHAR) AS NVARCHAR(Max)) AS Path
            ,value As PathValue
   FROM @puzHierarchy
   WHERE ChildId = (SELECT MAX(ChildId) FROM @puzHierarchy)
   UNION ALL
   SELECT t.ParentId
            ,list= CAST(ISNULL(CAST(t.ParentId AS NVARCHAR)  + '->' ,'')  + d.Path AS NVARCHAR(Max))
           ,(t.value+d.PathValue) As PathValue
   FROM @puzHierarchy t
   INNER JOIN children  AS d
      ON t.ChildId = d.ParentId
   )

SELECT [Path],PathValue
FROM children c
WHERE ParentId IS NULL 
    AND c.PathValue = (SELECT max(PathValue) FROM children WHERE ParentId IS NULL)

【问题讨论】:

  • 请解释你的问题,你想在这里实现什么
  • 嗨,我需要它应该在 100 输入时具有良好的性能。现在它需要花费大量时间来处理 20 到 30 个输入。你能建议吗
  • 您能否详细说明这个问题,以便任何人提出一些好的建议?
  • 您好 Dheeraj,执行 20-30 个输入需要花费大量时间,我想提高查询的性能。请建议我如何改进......谢谢

标签: sql-server sql-server-2008 tsql sql-server-2012 query-performance


【解决方案1】:

A.您的代码经历了太多与您想要的结果无关的周期/数据。 B. 运行您的样本数据后,结果不准确。

Parentid Path PathValue

NULL 1->3->4->6->10->12->13->19->20 145

NULL 1->3->4->10->12->13->19->20 145

第一个结果是错误的。

基本上你只想从 ParentId IS NULL 和 ChildId = 1 开始,在 ParentId = 1 中找到哪个 ChildId 具有 MAX 值,这个 ChildId 成为 ParentID 找到下一个 MAX 值,依此类推。

;WITH cte_base AS (SELECT Parentid
                    , Childid
                    , Value
                    , ROW_NUMBER() OVER(PARTITION BY Parentid ORDER BY Value DESC) AS Rownum
                FROM #puzHierarchy
), cte_re AS (SELECT ParentId
                , Childid
                , CAST(CAST(ChildId AS NVARCHAR) AS NVARCHAR(Max)) AS Path
                , Value As PathValue
                , Rownum
        FROM cte_base
        WHERE Parentid IS NULL
        UNION ALL
        SELECT b.parentid, b.childid
                , CAST(Path + '->' + ISNULL(CAST(b.parentid AS NVARCHAR)   ,'')  AS NVARCHAR(Max))
                ,(b.value + r.PathValue) As PathValue
                , b.Rownum
        FROM cte_base AS b
        INNER JOIN cte_re AS r
            ON b.Parentid = r.childid
        where b.Rownum = 1
)

SELECT *
FROM cte_re 

(我将您的示例表变量更改为临时表。)

【讨论】:

    猜你喜欢
    • 2020-06-26
    • 1970-01-01
    • 2021-07-26
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 2022-09-28
    • 1970-01-01
    • 2021-09-28
    相关资源
    最近更新 更多