资产负债表计算中的低速SQL查询

时间:2014-08-10 12:51:31

标签: sql-server-2008 query-performance accounting sqlperformance

我正在使用Tarazc4 sp来计算我的应用程序的资产负债表,但是当我的记录达到50000(超时错误)时非常耗时,请帮忙!现在已经不在我的脑海了!!!

SELECT * 
INTO #levels
FROM dbo.topics_getlevel()

SELECT * 
INTO #t1 
FROM accounting.documentdetail 
WHERE accounting.documentdetail.date BETWEEN @FromDate AND @ToDate

SELECT * 
FROM 
   (SELECT TOP (100) PERCENT 
        Accounting.Topics.Code, Accounting.Topics.TopicID, Accounting.Topics.ParentID,  
        Accounting.Topics.Description, 
        (SELECT Debit
         FROM dbo.SubTopics_GetSum(Accounting.Topics.TopicID, @FromDate, @ToDate) AS SubTopics_GetSum_2) AS Debit,
        (SELECT Credit
         FROM dbo.SubTopics_GetSum(Accounting.Topics.TopicID, @FromDate, @ToDate) AS SubTopics_GetSum_1) AS Credit, 
        (CASE 
            WHEN ((SELECT     Credit
                              FROM          dbo.subtopics_getsum(Accounting.Topics.TopicID,@FromDate,@ToDate)) -
                          (SELECT     Debit
                             FROM         dbo.subtopics_getsum(Accounting.Topics.TopicID,@FromDate,@ToDate))) < 0 THEN
                          ((SELECT     Debit
                              FROM          dbo.subtopics_getsum(Accounting.Topics.TopicID,@FromDate,@ToDate)) -
                          (SELECT     Credit
                             FROM         dbo.subtopics_getsum(Accounting.Topics.TopicID,@FromDate,@ToDate))) ELSE 0 END) AS ResDEBIT, (CASE WHEN
                          ((SELECT     Credit
                              FROM          dbo.subtopics_getsum(Accounting.Topics.TopicID,@FromDate,@ToDate)) -
                          (SELECT     Debit
                             FROM         dbo.subtopics_getsum(Accounting.Topics.TopicID,@FromDate,@ToDate))) > 0 THEN
                          ((SELECT     Credit
                              FROM          dbo.subtopics_getsum(Accounting.Topics.TopicID,@FromDate,@ToDate)) -
                          (SELECT     Debit
                             FROM         dbo.subtopics_getsum(Accounting.Topics.TopicID,@FromDate,@ToDate))) ELSE 0 END) AS ResCREDIT,(select [Level] from #Levels where TopicID=Accounting.Topics.TopicID) as [Level]
FROM         Accounting.Topics Left OUTER JOIN
                      #t1 ON Accounting.Topics.TopicID = #t1.TopicFK

GROUP BY Accounting.Topics.TopicID, Accounting.Topics.ParentID, Accounting.Topics.Code, Accounting.Topics.Description

ORDER BY Accounting.Topics.TopicID
)
t2

-------------------------------- END Tarazc4

并使用&#34; dbo.subtopics_getsum&#34;在Tar​​azc4 sp中运行以获得每个帐户的总和,请查看plz:

ALTER Function [dbo].[SubTopics_GetSum]

(
@TopicID int,@FromDate char(10),@ToDate char(10)
)
RETURNS TABLE 
AS
RETURN 
(
     WITH cte AS (
     SELECT  T1.TopicID, T1.Code, T1.Description, T1.ParentID, 
     T1.ParentID AS NewParentID, 
     CAST(T1.Code AS nvarchar(MAX)) AS TopicCode, 
     CAST(T1.Description AS nvarchar(MAX)) AS TopicDescription,
     isnull((Accounting.DocumentDetail.Debit),0) AS  Debit,
     isnull((Accounting.DocumentDetail.Credit),0) AS Credit
     FROM Accounting.Topics AS T1 
     LEFT OUTER JOIN
     Accounting.DocumentDetail ON T1.TopicID = Accounting.DocumentDetail.TopicFK
     where (Accounting.DocumentDetail.date between @FromDate and @ToDate) 
     and NOT EXISTS(
          SELECT    T2.TopicID, T2.Code, T2.Description, T2.ParentID, 
          isnull((Accounting.DocumentDetail.Debit),0) AS Debit,
          isnull((Accounting.DocumentDetail.Credit),0) AS Credit
          FROM Accounting.Topics AS T2 
          LEFT OUTER JOIN
          Accounting.DocumentDetail 
          ON T2.TopicID = Accounting.DocumentDetail.TopicFK
          WHERE (Accounting.DocumentDetail.date between @FromDate and @ToDate) 
          and (ParentID = T1.TopicID)
     )
     UNION ALL                          
     SELECT c.TopicID, c.Code, c.Description, c.ParentID, T1.ParentID AS NewParentID, 
     CAST(T1.Code AS nvarchar(MAX)) + c.TopicCode AS TopicCode, 
     CAST(T1.Description AS nvarchar(MAX)) + ' - ' + 
     c.TopicDescription AS TopicDescription,
     c.Debit AS Debit,c.Credit  AS Credit
     FROM cte AS c 
     INNER JOIN Accounting.Topics AS T1 
     ON T1.TopicID = c.NewParentID
     )

     select 
     isnull(sum(Debit),0)+
     isnull(
       (select sum(debit) from accounting.documentdetail 
        where (Accounting.DocumentDetail.date between @FromDate and @ToDate) 
       and topicfk=@TopicID)
     ,0) as Debit,
     isnull(Sum(Credit),0)+
     isnull(
        (select sum(credit) from accounting.documentdetail 
         where (Accounting.DocumentDetail.date between @FromDate and @ToDate) 
         and topicfk=@TopicID)
     ,0) as Credit 
     from cte as c
     WHERE     (NewParentID = @TopicID)
)

实际上,我的主题和文档表就像下面的图像一样,我只需要从documentdetail表中计算我的主题的资产负债表,并将其显示为我主题的层次结构(亲子)! enter image description here

2 个答案:

答案 0 :(得分:2)

我在列中反复看到dbo.subtopics_getsum(Accounting.Topics.TopicID,@FromDate,@ToDate)。作为一个讨厌的解决方法,您也可以将其转储到像#t1这样的临时表中,尽管它可能已经充分缓存了。

此外,我还没有看到TOP (100) PERCENT的需要,尽管它可能没什么区别。这是在某个阶段复制出来的吗?

您确实需要正确地重构此代码。

答案 1 :(得分:1)

最后,我想出了这个代码,并且令人惊讶地提高了我的性能但是如果还有其他任何有助于提高性能的要点,请查看它吗?

select * into #tleaf from(select *,(CASE WHEN (Credit-Debit) < 0 THEN (Debit-Credit) ELSE 0 END) AS ResDEBIT,(CASE WHEN(Credit-Debit) > 0 THEN(Credit-Debit) ELSE 0 END) AS ResCREDIT from (SELECT  Accounting.AllTopicsCTE.TopicID, Accounting.AllTopicsCTE.ParentID, Accounting.AllTopicsCTE.Code, Accounting.AllTopicsCTE.Description, isnull(sum(Debit),0) as Debit,isnull(sum(Credit),0) as Credit
                             from Accounting.AllTopicsCTE  LEFT OUTER JOIN
                      Accounting.DocumentDetail ON Accounting.AllTopicsCTE.TopicID = Accounting.DocumentDetail.TopicFK
                      where Accounting.DocumentDetail.Date between @FromDate and @ToDate
                      group by Accounting.AllTopicsCTE.TopicID, Accounting.AllTopicsCTE.ParentID, Accounting.AllTopicsCTE.Code, Accounting.AllTopicsCTE.Description) t0 
                     )t1
               select TopicID,ParentID,Code,Description,0 as Debit,0 as Credit,0 as ResDebit,0 as ResCredit into #tmain from Accounting.Topics where TopicID not in(select TopicID from #tleaf)      

                   --#tresult 
                    select * into #tresult from 
                    (select * from #tmain
                     union all
                     select * from #tleaf) b;
                     --------------------------------------------------------------
WITH HierarchicalCTE AS
(
    SELECT TopicID, ParentID, Code, Description,
           Debit,Credit,ResDebit,ResCredit, 0 AS LEVEL
    FROM #tresult i
    UNION ALL
    SELECT i.TopicID, i.ParentID, i.Code, i.Description,
           cte.Debit, cte.Credit,cte.ResDebit,cte.ResCredit,
           cte.LEVEL + 1
    FROM HierarchicalCTE cte join
         #tresult i
         ON i.TopicID = cte.ParentID
)
select TopicID, ParentID, Code, Description,
       sum(Debit) as Debit, sum(Credit) as Credit,sum(ResDebit) as ResDEBIT,sum(ResCredit) as ResCREDIT,(select [Level] from #Levels where TopicID=HierarchicalCTE.TopicID) as [Level]
from HierarchicalCTE
group by TopicID, ParentID, Code, Description
                     ------------------------------