Spec-Zone .ru
спецификации, руководства, описания, API

8.13.16.2. Оптимизация Подзапросов с Материализацией Подзапроса

С MySQL 5.6.5 оптимизатор использует материализацию подзапроса в качестве стратегии, которая включает более эффективной обработке подзапроса.

Если материализация не используется, оптимизатор иногда переписывает несвязанный подзапрос как связанный подзапрос. Например, следующий IN подзапрос некоррелируется (where_condition включает только столбцы от t2 и нет t1):

SELECT * FROM t1WHERE t1.a IN (SELECT t2.b FROM t2 WHERE where_condition);

Оптимизатор мог бы переписать это как EXISTS связанный подзапрос:

SELECT * FROM t1WHERE EXISTS (SELECT t2.b FROM t2 WHERE where_condition AND t1.a=t2.b);

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

Материализация подзапроса пытается использовать временную таблицу в памяти когда возможный, отступая к дисковому хранению, если таблица становится слишком большой. См. Раздел 8.4.3.3, "Использование MySQL How Внутренние Временные таблицы".

Для материализации подзапроса, которая будет использоваться в MySQL, materialization флаг optimizer_switch системная переменная должна быть on. Материализация тогда применяется к предикатам подзапроса, которые появляются где угодно (в списке выборки, WHERE, ON, GROUP BY, HAVING, или ORDER BY), для предикатов, которые попадают в любой из этих вариантов использования:

Следующие примеры иллюстрируют как требование для эквивалентности UNKNOWN и FALSE оценка предиката влияет, может ли материализация подзапроса использоваться. Примите это where_condition включает столбцы только от t2 и нет t1 так, чтобы подзапрос был некоррелирован.

Этот запрос подвергается материализации:

SELECT * FROM t1WHERE t1.a IN (SELECT t2.b FROM t2 WHERE where_condition);

Здесь, это не имеет значения ли IN возвраты предиката UNKNOWN или FALSE. Так или иначе, строка от t1 не включается в результат запроса.

Примером, где материализация подзапроса не будет использоваться, является следующий запрос, где t2.b nullable столбец.

SELECT * FROM t1WHERE (t1.a,t1.b) NOT IN (SELECT t2.a,t2.b FROM t2                          WHERE where_condition);

Использование EXPLAIN с запросом может дать некоторую индикацию относительно того, использует ли оптимизатор материализацию подзапроса. Сравненный с выполнением запроса, которое не использует материализацию, select_type может измениться от DEPENDENT SUBQUERY к SUBQUERY. Это указывает, что, для подзапроса, который был бы выполнен однажды на внешнюю строку, материализация позволяет подзапросу выполняться только однажды. Кроме того, для EXPLAIN EXTENDED, текст выводится на экран следующим SHOW WARNINGS будет включать materialize materialize и materialized-subquery (materialized subselect перед MySQL 5.6.6).