MySQL 8.0 リファレンスマニュアル


8.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 の行数を返します。

WHEREHAVING に置き換えると、エラーが発生します:

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_precision は、MIN() および MAX() には影響せず、いずれの場合も逆集約を使用しません。

STDDEV_POP(), STDDEV_SAMP(), VAR_POP(), VAR_SAMP() の分散関数およびそのシノニムの評価では、最適化モードまたはデフォルトモードで評価を行うことができます。 最適化モードでは、最後の有効桁の結果が若干異なる場合があります。 このような違いが許容される場合は、windowing_use_high_precision を無効にして最適化モードを許可できます。

EXPLAIN の場合、ウィンドウ実行計画情報は大きすぎるため、従来の出力形式で表示できません。 ウィンドウ情報を表示するには、EXPLAIN FORMAT=JSON を使用して windowing 要素を探します。


関連キーワード:  ウィンドウ, テーブル, インデックス, InnoDB, 関数, クエリー, ステートメント, 結合, サブクエリー, 集計