10.2.1.5 Оптимизация выталкивания условия движка
Данная оптимизация улучшает эффективность прямых сравнений между столбцом без индекса и константой. В таких случаях условие «выталкивается» в хранилище для оценки. Данная оптимизация может быть использована только движком хранения NDB.
Для NDB Cluster данная оптимизация может устранить необходимость отправки несоответствующих строк по сети между узлами данных кластера и сервером MySQL, который выдал запрос, и может ускорить запросы, в которых она используется, в 5–10 раз по сравнению с случаями, когда выталкивание условия могло бы быть, но не используется.
Предположим, что таблица NDB Cluster определена следующим образом:
CREATE TABLE t1 (
a INT,
b INT,
KEY(a)
) ENGINE=NDB;
Выталкивание условия движка может быть использовано с запросами, такими как показанный здесь, который включает сравнение между столбцом без индекса и константой:
SELECT a, b FROM t1 WHERE b = 10;
Использование выталкивания условия движка можно увидеть в выводе EXPLAIN:
mysql> EXPLAIN SELECT a, b FROM t1 WHERE b = 10\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 10
Extra: Using where with pushed condition
Однако выталкивание условия движка не может быть использовано с этим запросом:
SELECT a,b FROM t1 WHERE a = 10;
Выталкивание условия движка здесь неприменимо, так как существует индекс по столбцу a. (Метод доступа по индексу был бы более эффективным, и поэтому он был бы выбран вместо выталкивания условия.)
Выталкивание условия движка также может быть использовано, когда индексированный столбец сравнивается с константой с помощью оператора > или <:
mysql> EXPLAIN SELECT a, b FROM t1 WHERE a < 2\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: range
possible_keys: a
key: a
key_len: 5
ref: NULL
rows: 2
Extra: Using where with pushed condition
Другие поддерживаемые сравнения для выталкивания условия движка включают следующие:
-
column[NOT] LIKEpatternpatternдолжен быть строковым литералом, содержащим шаблон, который нужно сопоставить; для синтаксиса см. Раздел 14.8.1, “Функции и операторы сравнения строк”. columnIS [NOT] NULL-
columnIN (value_list)Каждый элемент в
value_listдолжен быть константой, литералом. -
columnBETWEENconstant1ANDconstant2constant1иconstant2должны быть константой, литералом.
Во всех случаях в приведенном выше списке условие может быть преобразовано в форму одного или нескольких прямых сравнений между столбцом и константой.
Выталкивание условия движка включено по умолчанию. Чтобы отключить его при запуске сервера, установите флаг optimizer_switch переменной engine_condition_pushdown в значение off. Например, в файле my.cnf используйте эти строки:
[mysqld]
optimizer_switch=engine_condition_pushdown=off
Во время выполнения отключите выталкивание условия следующим образом:
SET optimizer_switch='engine_condition_pushdown=off';
Ограничения. Выталкивание условия движка имеет следующие ограничения:
Выталкивание условия движка поддерживается только движком хранения
NDB.В NDB 8.4 столбцы могут сравниваться друг с другом, если они имеют точно одинаковый тип, включая одинаковый знак, длину, кодировку символов, точность и масштаб, где это применимо.
Столбцы, используемые в сравнениях, не могут быть ни одного из типов
BLOBилиTEXT. Это исключение распространяется и на столбцы типовJSON,BITиENUM.Строковое значение, подлежащее сравнению со столбцом, должно использовать ту же сортировку, что и столбец.
Объединения не поддерживаются напрямую; условия, относящиеся к нескольким таблицам, выталкиваются отдельно, где это возможно. Используйте расширенный вывод
EXPLAIN, чтобы определить, какие условия действительно выталкиваются. См. Раздел 10.8.3, “Формат расширенного вывода EXPLAIN”.
Ранее выталкивание условия движка ограничивалось терминами, относящимися к значениям столбцов из той же таблицы, в которую выталкивалось условие. В NDB 8.4 значения столбцов из таблиц, стоящих раньше в плане запроса, также могут быть указаны в выталкиваемых условиях. Это уменьшает количество строк, с которыми должен работать узел SQL при обработке объединений. Фильтрация также может выполняться параллельно в потоках LDM, а не в одном процессе mysqld. Это может существенно улучшить производительность запросов.
NDB может вытолкнуть внешнее объединение с помощью сканирования, если нет невыталкиваемых условий ни в одной таблице, используемой в той же вложенной связи объединения, или в любой таблице в вложенных связях объединения, от которых она зависит. Это также верно для полуобъединения, при условии, что используемая стратегия оптимизации является firstMatch (см.).
Алгоритмы объединения не могут быть объединены с ссылками на столбцы из предыдущих таблиц в следующих двух ситуациях:
Когда какие-либо из указанных ранее таблиц находятся в буфере объединения. В этом случае каждая строка, полученная из сканируемой таблицы с фильтром, сопоставляется с каждой строкой в буфере. Это означает, что нет одной конкретной строки, из которой можно извлечь значения столбцов при генерации фильтра сканирования.
Когда столбец происходит из дочерней операции в вытолкнутом объединении. Это происходит потому, что строки, на которые ссылаются предковые операции в объединении, еще не получены, когда генерируется фильтр сканирования.
Столбцы из предковых таблиц в объединении могут быть вытолкнуты, при условии, что они соответствуют перечисленным ранее требованиям. Пример такого запроса, используя ранее созданную таблицу t1, показан здесь:
mysql> EXPLAIN
-> SELECT * FROM t1 AS x
-> LEFT JOIN t1 AS y
-> ON x.a=0 AND y.b>=3\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: x
partitions: p0,p1
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4
filtered: 100.00
Extra: NULL
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: y
partitions: p0,p1
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4
filtered: 100.00
Extra: Using where; Using pushed condition (`test`.`y`.`b` >= 3); Using join buffer (hash join)
2 rows in set, 2 warnings (0.00 sec)
© 2025 Oracle
Licensed under the GPLv2 License.