Performance issue when returning zero records

  • I'm hoping someone on this site is able to help me understand why SQL Server is having issues when joining 2 datasets together via a union when the first data set returns zero records.

    What we're experiencing is that if the first query in the union returns zero records and the second query returns 1 or more records, the query does not complete (literally has run for 7+ hours without completing). However, if you flipped the order of the queries in the union where the query that returns data is first and the query that returns zero records is second, the query finishes in 2 minutes or less. Does anyone have any idea why there is such a drastic difference in query performance simply due to the order of the output?

    To head off any suggestions simply to reorder the query, the circumstances are that either query on any given day can return zero, 1 or many records. Therefore, reordering which comes first will not solve this problem.

    Here is the query should you need it to visualize what is occurring:

    WITH cteDataSetA AS

    (SELECT Field1,

    '1' AS Field2

    FROM Table1

    WHERE

    Field3 = 'D'

    AND Field1 not like '[ABCD]%'

    AND Field1 not like 'xyz%'

    UNION

    SELECT Field1, CONVERT(VARCHAR(2),Field2) AS Field2

    FROM Table2

    WHERE

    Field3 = 'D'

    AND Field1 not like '[ABCD]%'

    AND Field1 not like 'xyz%'

    AND Field2 < 100

    )

    ,cteDataSetB AS

    (SELECT RN = ROW_NUMBER() OVER (PARTITION BY E.Field4,A.Field1,E.Field2 ORDER BY E.Field5 desc)

    ,E.Field4

    ,A.Field1

    ,CONVERT(VARCHAR(2),ISNULL(Field2,'1')) as Field2

    ,E.Field5

    FROM cteDataSetA A

    LEFT JOIN Table2 D

    ON A.Field1 = D.Field1

    AND D.Field3='D'

    LEFT JOIN Table1 E

    ON D.Field1=E.Field1

    AND E.Field3='D'

    LEFT JOIN Table3 E

    ON D.Field1 = E.Field1

    AND CONVERT(VARCHAR(2),D.Field2) = E.Field2

    )

    ,cteDataSetC AS

    (SELECT DISTINCT

    ERN = ROW_NUMBER() OVER (PARTITION BY A.Field4,A.Field1,A.Field2 ORDER BY E.Field5 desc)

    ,A.Field4

    ,A.Field1

    ,CONVERT(VARCHAR(2),ISNULL(A.Field2,'1')) as Field2

    ,A.Field5

    FROM Table3 A

    LEFT JOIN Table4 C

    ON C.Field1=A.Field1

    AND C.Field2=CAST(A.Field2 AS VARCHAR(2))

    AND C.Field4=A.Field4

    AND A.Field3='D'

    LEFT JOIN Table5 E

    ON E.Field1=A.Field1

    AND E.Field2=A.Field2

    AND A.Field3='D'

    WHERE

    A.Field3 = 'D'

    AND A.Field1 not like '[ABCD]%'

    AND A.Field1 not like 'xyz%'

    AND E.Field1 IS NULL

    AND c.Field1 IS NULL

    )

    SELECT

    RN = ROW_NUMBER() OVER( PARTITION BY B.Field4,cte.Field1,B.Field2 ORDER BY B.Field5 desc),

    '' as FieldDesc

    ,B.Field4

    ,cte.Field1

    ,CONVERT(VARCHAR(2),ISNULL(B.Field2,'1'))

    FROM

    cteDataSetA cte

    INNER JOIN Table2 D

    ON cte.Field1 = D.Field1

    AND cte.Field2=D.Field2

    AND D.Field3='D'

    LEFT JOIN cteDataSetB B

    ON D.Field1=B.Field1

    AND D.Field2=B.Field2

    AND B.RN = 1

    WHERE

    B.Field4 is not null

    UNION

    SELECT

    RN = ROW_NUMBER() OVER (PARTITION BY C.Field4,cteDataSetB.Field1,C.Field2 ORDER BY C.Field5 desc),

    '' as FieldDesc

    ,C.Field4

    ,C.Field1

    ,CONVERT(VARCHAR(2),ISNULL(C.Field2,'1'))

    FROM

    cteDataSetC C

    WHERE

    C.Field4 IS NOT NULL

    AND C.ERN=1

    Any insight into this zero record behavioral issue is greatly appreciated!

  • Don't get confused into thinking that a CTE materialises the query inside it, it is just a query format structure and what you have there is a horrible mess.

    I suggest that you move each CTE query out to separate queries and store the results of each one in temporary tables instead.

    Also check your joins - you have declared outer joins with predicates in the WHERE clause that force them to be INNER joins, so just use inner joins for those.

    You have a row_number partitioned by columns from an OUTER join table - did you really want to partition by NULLS?

    I guess some mistakes may have been made when you were obfuscating the table/column names, and I hope the original query is less messy and confusing.

    In summary, Divide'n'Conquer applies here.

    By all means post back versions of the query as it develops if you need more pointers.

    MM



    select geometry::STGeomFromWKB(0x0106000000020000000103000000010000000B0000001000000000000840000000000000003DD8CCCCCCCCCC0840000000000000003DD8CCCCCCCCCC08408014AE47E17AFC3F040000000000104000CDCCCCCCCCEC3F9C999999999913408014AE47E17AFC3F9C99999999991340000000000000003D0000000000001440000000000000003D000000000000144000000000000000400400000000001040000000000000F03F100000000000084000000000000000401000000000000840000000000000003D0103000000010000000B000000000000000000143D000000000000003D009E99999999B93F000000000000003D009E99999999B93F8014AE47E17AFC3F400000000000F03F00CDCCCCCCCCEC3FA06666666666FE3F8014AE47E17AFC3FA06666666666FE3F000000000000003D1800000000000040000000000000003D18000000000000400000000000000040400000000000F03F000000000000F03F000000000000143D0000000000000040000000000000143D000000000000003D, 0);

  • Forum Etiquette: How to post Reporting Services problems
  • [/url]
  • Forum Etiquette: How to post data/code on a forum to get the best help - by Jeff Moden
  • [/url]
  • How to Post Performance Problems - by Gail Shaw
  • [/url]

Viewing 2 posts - 1 through 1 (of 1 total)

You must be logged in to reply to this topic. Login to reply