Во-первых, VIEW
является синтактическим c сахаром около SELECT
. Итак, позвольте мне обсудить варианты выбора:
select ID from `table1`
union
select ID from `table2`
По умолчанию это UNION DISTINCT
, так вот что происходит: (UNION ALL
будет совсем другим)
- Создайте временную таблицу с одним столбцом.
- Считайте столбец идентификатора из таблицы; скопировать все их как строки во временную таблицу
- То же самое для таблицы 2
- Дублировать эту временную таблицу
- Доставить строки.
Для этого :
select * from testView where some_col = 'some_val'
Если соответствующего индекса нет, он будет читать всю таблицу, проверяя каждую строку на предмет предложения WHERE
. При запуске он доставляет строки (все столбцы), которые не отфильтрованы.
Если он имеет оптимальное значение INDEX(some_col)
, он может сделать то же, что и выше, или может:
- Зайдите в индекс, чтобы найти первую строку, соответствующую этому предложению
WHERE
. - Сканирование вперед в дереве B +, пока не произойдет сбой предложения.
- Для каждого соответствующего
some_col
, поставьте строку.
Для этого:
select ID from `table1` where some_col = 'some_val'
union
select ID from `table2` where some_col = 'some_val'
Это как ваш первый UNION
, за исключением того, что каждая из таблиц может иметь или не иметь полезного индекса, следовательно, будет (или не будет) оптимизироваться на основе вашего другого "где" образца. (По крайней мере, 4 возможных способа оценки.)
Если ваша последняя вещь на самом деле является телом VIEW
, то возникает дополнительная сложность в том, что Оптимизатор решит «материализовать» содержимое, затем выполните фильтрация или «слияние» материала звонящего с VIEW
. Это становится еще сложнее объяснять и разъяснять.
Используйте EXPLAIN ...
и / или EXPLAIN FORMAT=JSON ...
для получения дополнительной информации. (Вернитесь, если вам нужно объяснение вывода EXPLAIN
; обычно оно немного криптито c.
Имейте в виду, что кажущиеся крошечными изменения могут существенно повлиять на выполнение запроса.