• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 窗口函数优化

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

    • 如果子查询具有窗口功能,则禁用子查询的派生表合并。子查询始终是物化的。
    • 半连接并不适用于窗口功能优化,因为半连接适用于子查询WHEREJOIN ... ON,这不能包含窗口函数。
    • 优化器按顺序处理多个具有相同排序要求的窗口,因此可以跳过对第一个窗口之后的窗口的排序。
    • 优化器不会尝试合并可以在单个步骤中评估的窗口(例如,当多个OVER子句包含相同的窗口定义时)。解决方法是在WINDOW子句中定义窗口,并在子句中引用窗口名称OVER

    在最外层可能的查询中汇总未用作窗口函数的汇总函数。例如,在此查询中,MySQL认为COUNT(t1.b)外部查询中不存在某些内容,因为它在WHERE子句中的位置:

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

    因此,MySQL会在子查询内部进行汇总,将其t1.b视为常量并返回的行数t2

    更换WHEREHAVING一个错误的结果:

    mysql> SELECT * FROM t1 HAVING t1.  = (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元素。