Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

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

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_precisionMIN()MAX()没有影响,因为它们不使用逆聚合。

对于方差函数STDDEV_POP()STDDEV_SAMP()VAR_POP()VAR_SAMP()的评估,可以在优化模式或默认模式下进行。优化模式可能会产生最后几个重要数字的轻微不同。如果这些差异是可接受的,可以禁用windowing_use_high_precision以允许优化模式。

对于 EXPLAIN,窗口执行计划信息太广泛,无法在传统输出格式中显示。要查看窗口信息,请使用 EXPLAIN FORMAT=JSON 并查找 windowing 元素。