Mysql параметризованные просмотры - PullRequest
0 голосов
/ 25 февраля 2020

Я хочу знать, как оптимизированы mysql представления для предложений where. Я создал один mysql view.

CREATE VIEW `testView` AS
select ID from `table1`
union
select ID from `table2` 

, когда я запускаю этот запрос

select * from testView where some_col = 'some_val'

, что будет mysql делать после запуска этого запроса.

Is mysql берет все строки из таблицы1 и таблицы2 в памяти, а затем запускает оператор where?

ИЛИ

Непосредственно этот запрос запускается изнутри?

select ID from `table1`  where some_col = 'some_val'
union
select ID from `table2`  where some_col = 'some_val' 

1 Ответ

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

Во-первых, VIEW является синтактическим c сахаром около SELECT. Итак, позвольте мне обсудить варианты выбора:

select ID from `table1`
union
select ID from `table2` 

По умолчанию это UNION DISTINCT, так вот что происходит: (UNION ALL будет совсем другим)

  1. Создайте временную таблицу с одним столбцом.
  2. Считайте столбец идентификатора из таблицы; скопировать все их как строки во временную таблицу
  3. То же самое для таблицы 2
  4. Дублировать эту временную таблицу
  5. Доставить строки.

Для этого :

select * from testView where some_col = 'some_val'

Если соответствующего индекса нет, он будет читать всю таблицу, проверяя каждую строку на предмет предложения WHERE. При запуске он доставляет строки (все столбцы), которые не отфильтрованы.

Если он имеет оптимальное значение INDEX(some_col), он может сделать то же, что и выше, или может:

  1. Зайдите в индекс, чтобы найти первую строку, соответствующую этому предложению WHERE.
  2. Сканирование вперед в дереве B +, пока не произойдет сбой предложения.
  3. Для каждого соответствующего 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.

Имейте в виду, что кажущиеся крошечными изменения могут существенно повлиять на выполнение запроса.

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