什么会导致UNION花费过多时间?

时间:2011-06-23 14:40:33

标签: sql-server-2008 query-optimization union

我的声明如下:

QUERY A
UNION
QUERY B
ORDER BY SomeColumn

查询A和查询B每个都需要花费一定的时间来运行,但是当我将它们放入UNION时,需要7-9秒,这是不可接受的。在这种情况下,查询A返回6行,查询B返回7.因此令人困惑......

我完全不知道是什么原因造成这种情况,非常感谢帮助!

这是脚本的匿名版本(我没有写这个,所以不要讨厌):

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 '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

2 个答案:

答案 0 :(得分:0)

由于UNION删除了重复项,因此必须首先对整个数据集进行排序...尝试使用UNION ALL代替....因为它不需要删除重复项,所以速度要快得多

答案 1 :(得分:0)

事实证明,旧样式ansii样式与更新的样式显式连接一起加入,导致冗长的返回。非常有趣,如果有人能提供一个理由,那就太棒了!