Click here to Skip to main content
15,885,920 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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

SQL
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
Herman<T>.Instance 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

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:
SQL
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.
 
Share this answer
 
v4

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900