Присоединение с использованием оператора ИЛИ - PullRequest
0 голосов
/ 10 марта 2020

У меня есть две таблицы. Таблица ключей сотрудника и таблица, содержащая их рабочее место.

EMPID   EMPNAME
1234    James
9876    Kevin
4567    Elaine

EMPID   EMPID_OLD   LOCATION
1234                TORONTO
987610  9876        NEW YORK
4567    104567      CHICAGO

Проблема заключается в том, что ключ сотрудника во второй таблице не согласован и разбросан по столбцам EMPID и EMPID_OLD.

Я написал запрос, включающий оператор "или" в выражении LEFT JOIN.:

select empid, location
from emp m1 
left join emp_location m2
    on m2.empid = m1.empid OR m2.empid_old = m1.empid

Этот запрос теоретически работает, однако его выполнение занимает около 45 минут. Если я удаляю выражение «ИЛИ», его запуск займет всего 5 секунд.

Выражение COALESCE не может быть использовано, поскольку первое совпадающее значение может быть неточным, поэтому оно имеет соединение либо значение, по которому он может найти совпадение, не обязательно первое.

Можно ли каким-то образом оптимизировать этот запрос, не разделяя объединения, как я сделал ниже?

Это упрощенная версия огромного запроса, над которым я работаю, поэтому очевидно пытаюсь избежать нескольких объединений для одной таблицы.

select m1.empid, coalesce(m2.location,m3.location)
from emp m1 
left join emp_location m2
    on m2.empid = m1.empid 
left join emp_location m3
    on m3.empid_old = m1.empid 

Ответы [ 3 ]

0 голосов
/ 10 марта 2020

Соединения и это тоже левое соединение или правое соединение или декартово, однако, являются дорогостоящими.

Иметь индекс для столбцов ( EMPID, EMPID_OLD) во второй таблице, так как подготовка к двум столбцам была выполнена в условии соединения через OR. Это может помочь в определенной степени

0 голосов
/ 13 апреля 2020

Часто union all работает лучше в таких условиях, как SQL Сервер может оптимизировать каждое соединение независимо, например,

select m1.empid, m2.[location]
from emp m1 
left join emp_location m2 on m2.empid = m1.empid 

union all

select m1.empid, m3.[location]
from emp m1 
left join emp_location m3  on m3.empid_old = m1.empid 
0 голосов
/ 10 марта 2020

Два левых соединения - это путь к go здесь. Если COALESCE не подходит вам, то вы можете использовать случай, когда условие, чтобы определить, какое местоположение использовать:

select m1.empid, 
       case when m2.location = 'Condition for location accuracy' then m2.location
            else m3.location end as location
from emp m1 
left join emp_location m2 on m2.empid= m1.empid 
left join emp_location m3 on m3.empid_old= m1.empid 
...