8.2.1.21 Window Function Optimization窗口函数优化

Window functions affect the strategies the optimizer considers:窗口函数影响优化器考虑的策略:

An aggregate function not used as a window function is aggregated in the outermost possible query. 未用作窗口函数的聚合函数在最外层的查询中聚合。For example, in this query, MySQL sees that COUNT(t1.b) is something that cannot exist in the outer query because of its placement in the WHERE clause:例如,在这个查询中,MySQL看到COUNT(t1.b)在外部查询中不存在,因为它位于WHERE子句中:

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

Consequently, MySQL aggregates inside the subquery, treating t1.b as a constant and returning the count of rows of t2.因此,MySQL在子查询中聚合,将t1.b视为常量并返回t2的行数。

Replacing WHERE with HAVING results in an error: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

The error occurs because COUNT(t1.b) can exist in the HAVING, and so makes the outer query aggregated.发生此错误的原因是COUNT(t1.b)可以存在于HAVING中,从而使外部查询聚合。

Window functions (including aggregate functions used as window functions) do not have the preceding complexity. 窗口函数(包括用作窗口函数的聚合函数)不具有上述复杂性。They always aggregate in the subquery where they are written, never in the outer query.它们总是聚集在写入它们的子查询中,而不是在外部查询中。

Window function evaluation may be affected by the value of the windowing_use_high_precision system variable, which determines whether to compute window operations without loss of precision. 窗口函数计算可能会受到windowing_use_high_precision系统变量值的影响,该系统变量决定是否在不损失精度的情况下计算窗口操作。By default, windowing_use_high_precision is enabled.默认情况下,将启用windowing_use_high_precision

For some moving frame aggregates, the inverse aggregate function can be applied to remove values from the aggregate. 对于某些移动帧聚合,可以应用反向聚合函数从聚合中移除值。This can improve performance but possibly with a loss of precision. 这可以提高性能,但可能会降低精度。For example, adding a very small floating-point value to a very large value causes the very small value to be hidden by the large value. 例如,将非常小的浮点值添加到非常大的值会导致非常小的值被大的值“隐藏”。When inverting the large value later, the effect of the small value is lost.稍后反转大值时,小值的效果将丢失。

Loss of precision due to inverse aggregation is a factor only for operations on floating-point (approximate-value) data types. 由于反向聚合而导致的精度损失仅是浮点(近似值)数据类型操作的一个因素。For other types, inverse aggregation is safe; this includes DECIMAL, which permits a fractional part but is an exact-value type.对于其他类型,反向聚合是安全的;这包括DECIMAL,它允许小数部分,但是一种精确的值类型。

For faster execution, MySQL always uses inverse aggregation when it is safe:为了更快地执行,MySQL总是在安全的情况下使用反向聚合:

For evaluation of the variance functions STDDEV_POP(), STDDEV_SAMP(), VAR_POP(), VAR_SAMP(), and their synonyms, evaluation can occur in optimized mode or default mode. 对于方差函数STDDEV_POP()STDDEV_SAMP()VAR_POP()VAR_SAMP()及其同义词的求值,可以在优化模式或默认模式下进行求值。Optimized mode may produce slightly different results in the last significant digits. 优化模式可能会在最后一个有效数字中产生略有不同的结果。If such differences are permissible, windowing_use_high_precision can be disabled to permit optimized mode.如果这种差异是允许的,可以禁用windowing_use_high_precision以允许优化模式。

For EXPLAIN, windowing execution plan information is too extensive to display in traditional output format. 对于EXPLAIN,窗口化执行计划信息过于广泛,无法以传统的输出格式显示。To see windowing information, use EXPLAIN FORMAT=JSON and look for the windowing element.要查看窗口信息,请使用EXPLAIN FORMAT=JSON并查找windowing元素。