Как можно оптимизировать это заявление VIEW? - PullRequest
3 голосов
/ 07 июля 2011

У меня есть VIEW, который медленный.Мне не нравятся заявления VIEW, так как есть много JOINS и UNION.

Вот оператор представления.

Create VIEW NewView AS

SELECT t2.* FROM Table1 t1
JOIN Table2 t2
ON t1.Column1 = t2.Column1 AND t1.Column2 = t2.Column2
WHERE t1.Column3 !='String'

UNION

SELECT t1.*, 'Add this string to the Last Column' FROM Table1 t1
LEFT JOIN Table2 t2
ON t1.Column1 = t2.Column1 AND t1.Column2 = t2.Column2
WHERE t2.Column1 is null OR t1.Column3 ='String'
ORDER BY Column 4

По сути, идея состоит в том, что если запись существует в Table1 и Table2, запись из Table2 должна перекрывать запись из Table1.Как я могу оптимизировать это?

У меня есть первичный ключ id INT NOT NULL AUTO_INCREMENT PRIMARY KEY в обеих таблицах, но я не уверен, как я могу интегрировать это с представлением.Я хочу, чтобы представление имело первичный ключ или составной ключ.Я не могу использовать другие столбцы, так как все столбцы могут иметь нулевые и повторяющиеся значения.

Ответы [ 3 ]

3 голосов
/ 07 июля 2011

Вы можете присоединиться и сравнить, используя внешнее соединение, а затем использовать COALESCE, чтобы предпочесть T2 вместо T1.

Чтобы сохранить уникальный ключ и предположить, что все ваши идентификаторы положительны, вы можете сделать идентификатор одной таблицы отрицательным.

SELECT
  COALESCE(t2.id,     -t1.id)      AS id,
  COALESCE(t2.Column1, t1.Column1) AS Column1,
  COALESCE(t2.Column2, t1.Column2) AS Column2
FROM
  Table1          AS t1
FULL OUTER JOIN
  Table2          AS t2
    ON  t1.Column1 = t2.Column2
    AND t1.Column2 = t2.Column2
WHERE
  COALESCE(t2.Column3, t1.Column3) = 'String'

EDIT:

Для более сложных правил выбора таблицы с точностью можно использовать операторы CASE ...

(Это то же самое, что и выше, но может быть изменено для других правил вероятности.)

SELECT
  CASE WHEN t2.id IS NULL THEN -t1.id      ELSE t2.id      END  AS id,
  CASE WHEN t2.id IS NULL THEN  t1.Column1 ELSE t2.Column1 END  AS Column1,
  CASE WHEN t2.id IS NULL THEN  t1.Column2 ELSE t2.Column2 END  AS Column2
FROM
  Table1          AS t1
FULL OUTER JOIN
  Table2          AS t2
    ON  t1.Column1 = t2.Column2
    AND t1.Column2 = t2.Column2
WHERE
  COALESCE(t2.Column3, t1.Column3) = 'String'
2 голосов
/ 07 июля 2011

Если вы уверены, что дубликатов не будет, вы можете увеличить их, заменив UNION на UNION ALL. Без ALL результаты запросов будут отсортированы, а дубликаты будут удалены при UNIONing.см http://dev.mysql.com/doc/refman/5.0/en/union.html

0 голосов
/ 07 июля 2011

Это должно выглядеть примерно так:

SELECT 
    IFNULL(t2.Col1, t1.Col1) Col1,
    IFNULL(t2.Col2, t1.Col2) Col2,
    IFNULL(t2.Col3, t1.Col3) Col3,
    IFNULL(t2.Col4, t1.Col4) Col4,
    'Add this string to the Last Column' 
FROM 
    Table1 t1
    LEFT JOIN Table2 t2 ON t1.Column1 = t2.Column1 AND t1.Column2 = t2.Column2
WHERE 
    t1.Column3 ='String'
ORDER BY 
    Col4

Если столбцы таблицы 2 могут иметь нормальные значения NULL в вашей базе данных, тогда этот SELECT должен начинаться следующим образом:

SELECT 
    IF(t2.id is NULL, t1.Col1, t2.Col1) Col1,
    IF(t2.id is NULL, t1.Col2, t2.Col2) Col1,
    IF(t2.id is NULL, t1.Col3, t2.Col3) Col1,
    IF(t2.id is NULL, t1.Col4, t2.Col4) Col1,
    'Add this string to the Last Column' 
    .
    .
...