Click here to Skip to main content
14,486,801 members
Rate this:
Please Sign up or sign in to vote.
I work on SQL server 2012 I have issue on query

the query is very slow i test it take too much time i realized that problem on these lines


because all query take 50 minutes to see result

when i remove lines above query take 7 minutes

so how to solve this issue as block bold below

SELECT F.CompanyID , 
 COUNT(CASE WHEN FI.FamilyLevel= 1 THEN  p.PartID  END )  Count_Yes_InForeCast ,  

 COUNT(CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 THEN  p.PartID END )  Count_No_InForeCast ,
------------------block that start problem
 COUNT(CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 AND PF.IntroductionDate IS NULL THEN  p.PartID END )  Count_No_InTroudctionNULLForeCast ,

 COUNT(CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 AND PF.IntroductionDate IS not NULL THEN  p.PartID END )  Count_No_InTroudctionNotNULLForeCast ,

 COUNT(CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 AND PF.IntroductionDate IS not NULL AND isnull(PF.Comment,'') LIKE '%appro%'  THEN  PF.PartID END )  Count_No_InTroudctionNotNULLAPPForeCast ,

 COUNT(CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 AND PF.IntroductionDate IS not NULL AND isnull(PF.Comment,'') NOT LIKE '%appro%'   THEN  PF.PartID END )  Count_No_InTroudctionNotNULLNoAPPForeCast ,
-----------end block
 COUNT(DISTINCT CASE WHEN FI.FamilyLevel= 1 THEN  FI.FamilyID  END )  CountFamily_Yes_InForeCast ,  
 COUNT(DISTINCT CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 THEN  FI.FamilyID END )  CountFamily_No_InForeCast into #ForecastTotal

   FROM Parts.FamilyIntroductionDate FI WITH(NoLock) INNER JOIN  parts.Nop_PartsFamily  F  ON F.PartFamilyID =fi.FamilyID

INNER JOIN parts.Nop_Part P WITH(NoLock) ON p.PartsFamilyID=f.PartFamilyID
LEFT OUTER  JOIN  parts.PartsForecast PF WITH(NoLock)  ON pf.PartID=p.PartID 
GROUP BY   F.CompanyID

Execution plan

Execution plan query[^]

What I have tried:

COUNT(CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 AND PF.IntroductionDate IS NULL THEN  p.PartID END )  Count_No_InTroudctionNULLForeCast ,

 COUNT(CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 AND PF.IntroductionDate IS not NULL THEN  p.PartID END )  Count_No_InTroudctionNotNULLForeCast ,

 COUNT(CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 AND PF.IntroductionDate IS not NULL AND isnull(PF.Comment,'') LIKE '%appro%'  THEN  PF.PartID END )  Count_No_InTroudctionNotNULLAPPForeCast ,

 COUNT(CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 AND PF.IntroductionDate IS not NULL AND isnull(PF.Comment,'') NOT LIKE '%appro%'   THEN  PF.PartID END )  Count_No_InTroudctionNotNULLNoAPPForeCast
Posted
Updated 19-Mar-20 23:34pm
Comments
digimanus 19-Mar-20 5:58am
   
I Guess the LIKE forces a table scan. What does the query execution plan tell you?
ahmed_sa 19-Mar-20 6:06am
   
it is found on this link
https://www.brentozar.com/pastetheplan/?id=Hyss6rlLL
ZurdoDev 19-Mar-20 7:59am
   
You have to add indexes or rewrite it but we can't do this for you because we don't have access to your database.

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

As to me... too many COUNT(CASE WHEN ...)

I'd emit data into less number of fields than yours, then to pivot data (or count data), as i shown you here: How to separate field partdone to text yes or no or null based on position ?[^].

Improved query might look like:
SELECT CompanyID, InForeCast, COUNT(InForeCast) AS CountInForeCast, InTroudctionForeCast, COUNT(InTroudctionForeCast) AS CountInTroudctionForeCast, InTroudctionNoAPPForeCast, COUNT(InTroudctionNoAPPForeCast) AS CountInTroudctionNoAPPForeCast 
FROM(
  SELECT F.CompanyID, ISNULL(FI.FamilyLevel, 0)=1 AS InForeCast,
    InTroudctionForeCast = CASE 
        WHEN ISNULL(FI.FamilyLevel,0)= 0 THEN ISDATE(PF.IntroductionDate) --returns 1 - if true/0 - if false
    END,
    InTroudctionNoAPPForeCast =  CASE 
        WHEN ISNULL(FI.FamilyLevel,0)= 0 AND ISDATE(PF.IntroductionDate)=1 THEN  ISNULL(PF.Comment,'') LIKE '%appro%' --returns true/false
    END
-- below lines are repeated!
--,
-- COUNT(DISTINCT CASE WHEN FI.FamilyLevel= 1 THEN  FI.FamilyID  END )  CountFamily_Yes_InForeCast ,  
-- COUNT(DISTINCT CASE WHEN ISNULL(FI.FamilyLevel,0)= 0 THEN  FI.FamilyID END )  CountFamily_No_InForeCast into #ForecastTotal
FROM Parts.FamilyIntroductionDate FI WITH(NoLock)
    INNER JOIN  parts.Nop_PartsFamily  F  ON F.PartFamilyID =fi.FamilyID
    INNER JOIN parts.Nop_Part P WITH(NoLock) ON p.PartsFamilyID=f.PartFamilyID
    LEFT OUTER  JOIN  parts.PartsForecast PF WITH(NoLock)  ON pf.PartID=p.PartID 
GROUP BY F.CompanyID
) AS T
GROUP BY CompanyID, InForeCast, InTroudctionForeCast, InTroudctionNoAPPForeCast


Note: i have no access to your data, so above query may need to be improved.
   
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100