Spec-Zone.ru › MySQL 9.2

10.2.1.21 Оптимизация оконных функций

Оконные функции влияют на стратегии, которые рассматривает оптимизатор:

  • Слияние производных таблиц для подзапроса отключается, если подзапрос содержит оконные функции. Подзапрос всегда материализуется.

  • Полусоединения не применимы к оптимизации оконных функций, потому что полусоединения применяются к подзапросам в WHERE и JOIN ... ON, которые не могут содержать оконные функции.

  • Оптимизатор обрабатывает несколько окон, имеющих одинаковые требования к упорядочению последовательно, поэтому сортировка может быть пропущена для окон, следующих за первым.

  • Оптимизатор не пытается объединить окна, которые можно было бы оценить за один шаг (например, когда несколько OVER-клаузов содержат идентичные определения окон). Решение — определить окно в WINDOW-клаузе и сослаться на имя окна в OVER-клаузах.

Агрегатная функция, не используемая в качестве оконной функции, агрегируется в возможно самом внешнем запросе. Например, в данном запросе MySQL видит, что COUNT(t1.b) — это то, что не может существовать во внешнем запросе из-за его размещения в WHERE-клаузе:

SELECT * FROM t1 WHERE t1.a = (SELECT COUNT(t1.b) FROM t2);

Вследствие этого MySQL агрегирует внутри подзапроса, рассматривая t1.b как константу и возвращая количество строк t2.

Замена WHERE на HAVING приводит к ошибке:

mysql> SELECT * FROM t1 HAVING t1.a = (SELECT COUNT(t1.b) FROM t2);
ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1
of SELECT list contains nonaggregated column 'test.t1.a'; this is
incompatible with sql_mode=only_full_group_by

Ошибка возникает, потому что COUNT(t1.b) может существовать во HAVING и, таким образом, заставляет внешний запрос агрегировать.

Оконные функции (включая агрегатные функции, используемые как оконные функции) не имеют упомянутой сложности. Они всегда агрегируются в подзапросе, где они написаны, никогда во внешнем запросе.

Оценка оконных функций может быть повлияна значением системной переменной windowing_use_high_precision, которая определяет, вычислять ли оконные операции без потери точности. По умолчанию windowing_use_high_precision включена.

Для некоторых агрегатов скользящего окна обратная агрегатная функция может быть применена для удаления значений из агрегата. Это может улучшить производительность, но, возможно, с потерей точности. Например, добавление очень малого числа с плавающей точкой к очень большому числу приводит к тому, что очень малое число «скрывается» большим. При последующем инвертировании большого числа эффект малого числа теряется.

Потеря точности из-за обратной агрегации является фактором только для операций с данными с плавающей точкой (приблизительные значения). Для других типов обратная агрегация безопасна; это включает DECIMAL, которое допускает дробную часть, но является типом точных значений.

Для ускорения выполнения MySQL всегда использует обратную агрегацию, когда она безопасна:

  • Для значений с плавающей точкой обратная агрегация не всегда безопасна и может привести к потере точности. По умолчанию избегается обратная агрегация, что медленнее, но сохраняет точность. Если допустимо пожертвовать безопасностью ради скорости, windowing_use_high_precision можно отключить, чтобы разрешить обратную агрегацию.

  • Для типов данных, не являющихся числами с плавающей точкой, обратная агрегация всегда безопасна и используется независимо от значения windowing_use_high_precision.

  • windowing_use_high_precision не влияет на MIN() и MAX(), которые в любом случае не используют обратную агрегацию.

Для оценки функций дисперсии STDDEV_POP(), STDDEV_SAMP(), VAR_POP(), VAR_SAMP() и их синонимов, оценка может происходить в оптимизированном режиме или в режиме по умолчанию. Оптимизированный режим может давать немного отличающиеся результаты в последних значащих цифрах. Если такие различия допустимы, windowing_use_high_precision можно отключить, чтобы разрешить оптимизированный режим.

Для EXPLAIN, информация о плане выполнения оконной операции слишком обширна, чтобы отображаться в традиционном формате вывода. Чтобы увидеть информацию о оконных операциях, используйте EXPLAIN FORMAT=JSON и ищите элемент windowing.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/window-function-optimization.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API