Оптимизация MIN/MAX
Оптимизация MIN/MAX без GROUP BY
MariaDB и MySQL могут оптимизировать функции MIN() и MAX() до поиска по одной строке в следующих случаях:
- Используется только одна таблица в
SELECT. - В части
SELECTу вас только константы,MIN()иMAX(). - Аргумент для
MIN()иMAX()— это просто ссылка на столбец, который является частью ключа. - Нет условия
WHEREили условиеWHEREиспользуется с константой для всех префиксных частей ключа перед аргументом дляMIN()/MAX(). - Если аргумент используется в условии
WHERE, его можно сравнить с константой с помощью<или<=в случаеMAX()и с>или>=в случаеMIN().
Вот несколько примеров, чтобы прояснить это. В этом случае мы предполагаем, что есть индекс по столбцам (a,b,c)
SELECT MIN(a),MAX(a) from t1 SELECT MIN(b) FROM t1 WHERE a=const SELECT MIN(b),MAX(b) FROM t1 WHERE a=const SELECT MAX(c) FROM t1 WHERE a=const AND b=const SELECT MAX(b) FROM t1 WHERE a=const AND b<const SELECT MIN(b) FROM t1 WHERE a=const AND b>const SELECT MIN(b) FROM t1 WHERE a=const AND b BETWEEN const AND const SELECT MAX(b) FROM t1 WHERE a=const AND b BETWEEN const AND const
- Вместо
a=constможно использовать условиеa IS NULL.
Вышеупомянутая оптимизация также работает для подзапросов:
SELECT x from t2 where y= (SELECT MIN(b) FROM t1 WHERE a=const)
Перекрёстные соединения, где нет условия соединения для таблицы, также могут быть оптимизированы до нескольких поисков по ключу:
select min(t1.key_part_1), max(t2.key_part_1) from t1, t2
Оптимизация MIN/MAX с GROUP BY
MariaDB и MySQL поддерживают нестрогий поиск по индексу, что может ускорить определённые запросы GROUP BY. Основная идея заключается в том, что при сканировании индекса BTREE (самый распространённый тип индекса для хранилищ MariaDB) мы можем пропустить идентичные значения для любого префикса ключа и тем самым значительно ускорить сканирование.
Нестрогий поиск возможен в следующих случаях:
- Запрос использует только одну таблицу.
- Часть
GROUP BYиспользует только столбцы индекса в том же порядке, что и в индексе. - Единственными агрегированными функциями в части
SELECTявляются функцииMIN()иMAX(), и все они используют один и тот же столбец, который является следующей частью индекса после используемых столбцовGROUP BY. - Частичные индексированные столбцы не могут быть использованы (например, индексирование только 10 символов столбца
VARCHAR(20)).
Нестрогий поиск будет применяться к вашему запросу, если EXPLAIN показывает Using index for group-by в столбце Extra. В этом случае оптимизатор выполнит только один дополнительный запрос строки для расчёта значения для MIN() или MAX() для каждого уникального префикса ключа.
Следующие примеры предполагают, что у таблицы t1 есть индекс по (a,b,c).
SELECT a, b, MIN(c),MAX(c) FROM t1 GROUP BY a,b
См. также
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/minmax-optimization/