Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  Window Function Optimization

10.2.1.21 窗口函数优化

窗口函数影响优化器考虑的策略:

  • 如果子查询中包含窗口函数,derived table merging 将被禁用。子查询总是被materialized。

  • 半连接不能应用于窗口函数优化,因为半连接适用于在WHEREJOIN ... 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_precisionMIN()MAX()没有影响,因为这两个函数在任何情况下都不使用反向聚合。

对于计算方差函数STDDEV_POP()STDDEV_SAMP()VAR_POP()VAR_SAMP()和它们的同义词,可以在优化模式或默认模式下进行评估。优化模式可能会在最后的有效数字中产生略微不同的结果。如果允许这种差异,可以禁用windowing_use_high_precision以允许优化模式。

对于EXPLAIN,窗口执行计划信息太过详细,以至于不能在传统输出格式中显示。要查看窗口信息,可以使用EXPLAIN FORMAT=JSON并查找windowing元素。