Оставить соединение, только если предыдущее соединение ничего не нашло - PullRequest
1 голос
/ 28 марта 2019

Я пытаюсь сделать это как можно меньше.

-

Допустим, у меня есть три таблицы: table1 table2 и table3.У всех этих таблиц есть столбец "organizationID".У меня также есть таблица 0, которая каким-то образом связана со всем этим.

Иногда "organizationID" находится в таблице 1, иногда в таблице 2, иногда в таблице 3.

-

Я делаю что-то вроде этого:

SELECT coalesce(table1.organizationID,coalese(table2.organizationID,coalesce(table3.organizationID,0)))
FROM table0
LEFT JOIN table1 ON (some condition)
LEFT JOIN table2 ON (some condition)
LEFT JOIN table3 ON (some condition)

Это работает.Это дает мне то, что я хочу.Проблема в производительности.База данных всегда выполняет все три объединения, даже если table1 уже имеет orgaizationID.

-

Я хочу изменить этот выбор следующим образом:

SELECT coalesce(table1.organizationID,coalese(table2.organizationID,coalesce(table3.organizationID,0)))
FROM table0
LEFT JOIN table1 ON (some condition)
LEFT JOIN table2 ON (some condition) AND table1.organizationID IS NULL
LEFT JOIN table3 ON (some condition) AND table2.organizationID IS NULL

Проблема в том, что он все еще выполняет все объединения, поэтому для завершения выполнения требуется столько же времени.

Можно ли как-нибудь предотвратить запуск объединений, если предыдущее объединение было успешным?

-

Заранее большое спасибо.

-

РЕДАКТИРОВАТЬ: Соединение table3 занимает много времени для выполнения.Я ничего не могу с этим поделать.Поэтому я хочу избегать присоединения к этой таблице, если мне это не нужно (то есть, если в table1 или table2 уже есть столбец organizationID)

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

Во-первых, ваши IS NULL проверки не завершены. Если t1 присоединен успешно, t2.organization будет NULL и заставит вас проверить t3 избыточно.

Попробуйте сначала?

SELECT
    coalesce(table1.organizationID,coalese(table2.organizationID,coalesce(table3.organizationID,0)))
FROM
          table0
LEFT JOIN table1 ON (some condition)
LEFT JOIN table2 ON (some condition) AND table1.organizationID IS NULL
LEFT JOIN table3 ON (some condition) AND table1.organizationID IS NULL AND table2.organizationID IS NULL

В противном случае вы МОЖЕТЕ убедить оптимизатора в коротком замыкании (Не объединять, если не нужно) с помощью боковых соединений?

SELECT
  table3.organizationID
FROM
  table0
LEFT JOIN
  table1
    ON (some condition)
LEFT LATERAL JOIN
(
  SELECT table2.organizationID FROM table2 WHERE (some condition) AND table1.organizationID IS     NULL
  UNION ALL
  SELECT table1.organizationID             WHERE                      table1.organizationID IS NOT NULL
)
  table2 ON true
LEFT LATERAL JOIN
(
  SELECT table3.organizationID FROM table3 WHERE (some condition) AND table2.organizationID IS     NULL
  UNION ALL
  SELECT table2.organizationID             WHERE                      table2.organizationID IS NOT NULL
)
  table3 ON true
0 голосов
/ 28 марта 2019

Запрос будет выполнять все объединения, потому что все может понадобиться - в разных строках.

Если вы действительно хотите ограничить количество поисков, вы можете использовать case.Что-то вроде:

SELECT . . ., 
       (CASE WHEN EXISTS (SELECT 1
                          FROM table1 t1
                          WHERE t1.? = t0.? AND . . .
                         )
             THEN (SELECT ?
                   FROM table1 t1
                   WHERE t1.? = t0.? AND . . .
                  )
             WHEN EXISTS (SELECT 1
                          FROM table1 t2
                          WHERE t2.? = t0.? AND . . .
                         )
             THEN (SELECT ?
                   FROM table2 t2
                   WHERE t2.? = t0.? AND . . .
                  )
           . . .
      END)
FROM table0;

Однако это не ускорит запрос.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...