Spec-Zone .ru
спецификации, руководства, описания, API
|
С 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
), для предикатов, которые
попадают в любой из этих вариантов использования:
У предиката есть эта форма, когда никакое внешнее выражение oe_i
или внутреннее выражение ie_i
nullable. N
может быть 1 или больше.
(oe_1
,oe_2
, ...,oe_N
) [NOT] IN (SELECTie_1
,i_2
, ...,ie_N
...)
У предиката есть эта форма, когда есть единственное внешнее выражение oe
и внутреннее выражение ie
. Выражения могут быть nullable.
oe
[NOT] IN (SELECTie
...)
Предикат IN
или NOT IN
и
результат UNKNOWN
(NULL
) имеет то же самое
значение в результате FALSE
.
Следующие примеры иллюстрируют как требование для эквивалентности 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).