#### 8.2.1.21 窗口函数优化

[](<>)[](<>)

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

-   如果子查询具有窗口函数，则禁用子查询的派生表合并。子查询总是物化的。

-   半连接不适用于窗口函数优化，因为半连接适用于`在哪里`和`加入...开启`，其中不能包含窗口函数。

-   优化器按顺序处理具有相同排序要求的多个窗口，因此可以跳过第一个窗口之后的排序。

-   优化器不会尝试合并可以在单个步骤中评估的窗口（例如，当多个`超过`子句包含相同的窗口定义）。解决方法是在一个`窗户`子句并引用窗口名称`超过`条款。

    未用作窗口函数的聚合函数在最外层可能的查询中聚合。例如，在这个查询中，MySQL 看到`计数（t1.b）`是在外部查询中不能存在的东西，因为它位于`在哪里`条款：


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

因此，MySQL 在子查询中聚合，处理`t1.b`作为常数并返回`t2`.

更换`在哪里`和`拥有`导致错误：

```
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
```

发生错误是因为`计数（t1.b）`可以存在于`拥有`，因此使外部查询聚合。

窗口函数（包括用作窗口函数的聚合函数）没有上述复杂性。它们总是在编写它们的子查询中聚合，而不是在外部查询中。

窗口函数评估可能会受到[`windowing_use_high_precision`](server-system-variables.html#sysvar_windowing_use_high_precision)系统变量，它决定是否在不损失精度的情况下计算窗口操作。默认，[`windowing_use_high_precision`](server-system-variables.html#sysvar_windowing_use_high_precision)已启用。

对于某些移动帧聚合，可以应用逆聚合函数从聚合中删除值。这可以提高性能，但可能会降低精度。例如，将非常小的浮点值添加到非常大的值会导致非常小的值被大值“隐藏”。稍后反转大值时，会失去小值的效果。

由于反向聚合导致的精度损失仅是浮点（近似值）数据类型操作的一个因素。对于其他类型，反向聚合是安全的；这包括[`十进制`](fixed-point-types.html)，它允许小数部分，但它是一个精确值类型。

为了更快的执行，MySQL 总是在安全的情况下使用反向聚合：

-   对于浮点值，反向聚合并不总是安全的，可能会导致精度损失。默认是避免反向聚合，它速度较慢但保持精度。如果可以为了速度牺牲安全，[`windowing_use_high_precision`](server-system-variables.html#sysvar_windowing_use_high_precision)可以禁用以允许反向聚合。

-   对于非浮点数据类型，反向聚合始终是安全的，并且无论[`windowing_use_high_precision`](server-system-variables.html#sysvar_windowing_use_high_precision)价值。

-   [`windowing_use_high_precision`](server-system-variables.html#sysvar_windowing_use_high_precision)对没有影响[`最小（）`](aggregate-functions.html#function_min)和[`最大限度（）`](aggregate-functions.html#function_max)，在任何情况下都不使用反向聚合。

    用于评估方差函数[`STDDEV_POP()`](aggregate-functions.html#function_stddev-pop),[`STDDEV_SAMP()`](aggregate-functions.html#function_stddev-samp),[`VAR_POP()`](aggregate-functions.html#function_var-pop),[`VAR_SAMP()`](aggregate-functions.html#function_var-samp)，以及它们的同义词，评估可以在优化模式或默认模式下发生。优化模式可能会在最后一个有效数字中产生略有不同的结果。如果允许这种差异，[`windowing_use_high_precision`](server-system-variables.html#sysvar_windowing_use_high_precision)可以禁用以允许优化模式。

[](<>)[](<>)

为了[`解释`](explain.html)，窗口执行计划信息过于广泛，无法以传统的输出格式显示。要查看窗口信息，请使用[`解释格式=JSON`](explain.html)并寻找`开窗`元素。
