Что заставит UNION занимать слишком много времени? - PullRequest
2 голосов
/ 23 июня 2011

У меня есть утверждение, которое выглядит следующим образом:

QUERY A
UNION
QUERY B
ORDER BY SomeColumn

Каждый запрос A и запрос B занимает номинальное количество времени для выполнения, но когда я помещаю их в UNION, это занимает 7-9 секунд.что недопустимо.В этом случае Query A возвращает 6 строк, Query 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 голосов
/ 11 июля 2011

Оказывается, что это были соединения в стиле ANSI старого стиля в сочетании с явными соединениями более нового стиля, которые вызывали длительный возврат.Довольно интересно, если бы кто-нибудь мог объяснить причину, по которой это было бы фантастически!

0 голосов
/ 23 июня 2011

Поскольку UNION удаляет дубликаты, сначала нужно отсортировать весь набор данных ... попробуйте вместо этого использовать UNION ALL ... это намного быстрее, поскольку не нужно удалять дубликаты

...