开发者

What would cause a UNION to take an excessive amount of time?

开发者 https://www.devze.com 2023-03-15 10:13 出处:网络
I have a statement that looks like: QUERY A UNION QUERY B ORDER BY SomeColumn Query A and Query B each take a nominal amount of time to run, but when I put them in the UNION, it take 7-9 seconds wh

I have a statement that looks like:

QUERY A
UNION
QUERY B
ORDER BY SomeColumn

Query A and Query B each take a nominal amount of time to run, but when I put them in the UNION, it take 7-9 seconds which is unacceptable. In this case Query A returns 6 rows, Query B returns 7. So confusing...

I have absolutely no idea what would cause this, help would be much appreciated!

Here is an anonymized version of the script (I did not write this, so don't hate):

SELECT 
    'XXX' l_t, 
    s.p, 
    srst.c_b, 
    srd.a_d_f, 
    s.s_c, 
    sf.c_s, 
    srst.p_f, 
    s.s_r_i, 
    s.s_i, 
    s.s_d, 
    srd.m_s_d_l s_d, 
    srd.m_e_d_l e_d, 
    CASE WHEN (srs.s_s_t IS NOT NULL AND srs.s_s_t <> srs.s_e_t) 
        THEN 1 ELSE 0 END 's_f', 
    CASE WHEN (srs.c_s_t IS NOT NULL AND srs.c_s_t <> srs.c_e_t) 
        THEN 1 ELSE 0 END 'c_f', 
    r.r_i 
FROM 
    t_s_r_d srd 
    INNER JOIN t_s s WITH (NOLOCK) 
        ON s.s_i = srd.s_i 
    INNER JOIN i_s_r(12345) r 
    ON r.r_i = srd.r_i 
    INNER JOIN i_s_s_f() sf 
    ON (sf.s_i = srd.s_i)
    INNER JOIN t_s_r_s srst WITH (NOLOCK)
    ON (srst.s_i = srd.s_i AND srst.r_i = srd.r_i ) 
    LEFT OUTER JOIN t_s_r_s srs WITH (NOLOCK) 
    ON (srs.s_i = srd.s_i AND srs.r_i = srd.r_i) 
WHERE 
    srst.d_f = 0  
    AND ((srd.m_s_d_l >= someval AND srd.m_s_d_l < someotherval) 
        OR 
        (srd.m_s_d_l <= someval AND srd.m_e_d_l > someotherval)) 
    AND r.o_f = 0 
    AND r.i_f = 0 
    AND r.v_f = 1 
    AND r.g_i = 180 
    AND NOT EXISTS(SELECT * FROM t_c_r cdr WITH (NOLOCK) WHERE cdr.r_i = r.r_i)

UNION 

SELECT 
    'XXX' l_t, 
    s.p, 
    srst.c_b, 
    srd.a_d_f, 
    s.s_c, 
    sf.c_s, 
    srst.p_f, 
    s.s_r_i, 
    s.s_i, 
    s.s_d, 
    srd.m_s_d_l s_d, 
    srd.m_e_d_l e_d, 
    CASE WHEN (srs.s_s_t IS NOT NULL AND srs.s_s_t <> srs.s_e_t) 
        THEN 1 ELSE 0 END '开发者_StackOverflow社区s_f', 
    CASE WHEN (srs.c_s_t IS NOT NULL AND srs.c_s_t <> srs.c_e_t) 
        THEN 1 ELSE 0 END 'c_f', 
    c.c_i 
FROM 
    (t_s_r_d srd 
    INNER JOIN t_s s WITH (NOLOCK) 
        ON s.s_i = srd.s_i 
    INNER JOIN i_s_s_f() sf 
        ON (sf.s_i = srd.s_i)
    LEFT OUTER JOIN t_s_r_s srs WITH (NOLOCK) 
        ON (srs.s_i = srd.s_i AND srs.r_i = srd.r_i) 
    INNER JOIN t_s_r_s srst WITH (NOLOCK) 
        ON (srst.s_i = srd.s_i AND srst.r_i = srd.r_i)), 
    i_s_c(12345) c 
WHERE 
    srst.d_f = 0  
    AND ((srd.m_s_d_l >= someval AND srd.m_s_d_l < someotherval) 
        OR 
        (srd.m_s_d_l <= someval AND srd.m_e_d_l > someotherval)) 
    AND c.o_f = 0 
    AND c.i_f = 0 
    AND c.v_f = 1 
    AND c.g_i = 180 
    AND EXISTS(SELECT * FROM t_c_r cr WITH (NOLOCK) WHERE cr.r_i = srd.r_i and 
        cr.c_i = c.c_i)
ORDER BY s_d


Because UNION removes duplicates it has to sort the whole data set first...try to use UNION ALL instead....it is much faster since it doesn't need to remove the dups


Turns out it was the old style ansii style joins in conjunction with the newer style explicit joins that were causing the lengthy return. Quite interesting, if anyone could provide a reason why that would be fantastic!

0

精彩评论

暂无评论...
验证码 换一张
取 消