Mysql関数呼び出しの最適化の詳細な説明

Mysql関数呼び出しの最適化の詳細な説明

関数呼び出しの最適化

MySQL 関数は、内部的に決定論的または非決定論的としてマークされます。引数に固定値を与えられた関数が、呼び出しごとに異なる結果を返す場合、その関数は未定義です。非決定論的関数の例: RAND()UUID()

関数が非決定的としてマークされている場合、 WHERE句内の関数への参照は、各行 (1 つのテーブルから選択する場合) または行の組み合わせ (複数のテーブル結合から選択する場合) に対して評価されます。

MySQL は、引数の型 (引数がテーブル列であるか定数値であるか) に基づいて、関数を評価するタイミングも決定します。テーブル列の値が変更されるたびに、テーブル列を引数として受け取る決定論的関数を評価する必要があります。

非決定論的関数はクエリのパフォーマンスに影響を与える可能性があります。たとえば、一部の最適化が利用できない場合や、より多くのロックが必要になる場合があります。以下の説明ではRAND()を使用しますが、他の不確実性関数にも適用できます。

テーブル t の定義が次のようになっているとします。

テーブル t を作成します (id INT NOT NULL PRIMARY KEY、col_a VARCHAR(100))。

次の 2 つのクエリを考えてみましょう。

tから*を選択します。WHERE id = POW(1,2);
SELECT * FROM t WHERE id = FLOOR(1 + RAND() * 49);

両方のクエリは、主キーとの等価比較により主キー検索を使用しているように見えますが、これは最初のクエリにのみ適用されます。

  • 定数引数を持つPOW()は定数値を取り、インデックス検索に使用されるため、最初のクエリでは常に最大 1 行が生成されます。
  • 2 番目のクエリには、非決定論的関数RAND()この関数はクエリ内の定数ではありませんが、実際にはテーブルの各行に新しい値 t があります。したがって、クエリはテーブルのすべての行を読み取り、各行の述語を評価し、主キーがランダム値と一致するすべての行を出力します。 id 列の値と RAND() シーケンスの値に応じて、0 行、1 行、またはそれ以上の行になります。

非決定性の影響はSELECTステートメントに限定されません。このUPDATEステートメントは、非決定論的関数を使用して変更する行を選択します。

t を更新します。set col_a = some_expr WHERE id = FLOOR(1 + RAND() * 49);

おそらく、主キーが式と一致する行を最大 1 つ更新することが意図されています。ただし、 id列の値とRAND()シーケンスの値に応じて、0 行、1 行、またはそれ以上の行が更新される場合があります。

今説明した動作は、パフォーマンスとレプリケーションに影響を及ぼします。

  • 非決定論的関数は定数値を生成しないため、オプティマイザーはインデックス シークなどの適用可能な他の戦略を使用できません。結果はテーブルスキャンになる可能性があります。
  • 一致する行に対して単一行ロックを取得する代わりに、 InnoDB範囲キー ロックにアップグレードする場合があります。
  • 実行された更新はレプリケーションにとって安全ではないと判断できませんでした。

困難さは、 RAND()テーブルの各行に対して関数を 1 回評価するという事実から生じます。複数関数の評価を回避するには、次のいずれかの手法を使用します。

  • 非決定的関数を含む式を別のステートメントに移動し、値を変数に格納します。元のステートメントで、式を、オプティマイザーが定数値として扱うことができる変数への参照に置き換えます。
@keyval = FLOOR(1 + RAND() * 49) を設定します。
UPDATE t SET col_a = some_expr WHERE id = @keyval;
  • 派生テーブル内の変数にランダムな値を割り当てます。この手法により、変数はWHERE句の比較に使用される前に値が割り当てられます。
optimizer_switch = 'derived_merge=off' を設定します。
t を更新します (SELECT @keyval := FLOOR(1 + RAND() * 49)) AS dt
col_a = some_expr を設定します。WHERE id = @keyval;

前述したように、 WHERE句内の非決定論的な式は最適化を妨げ、テーブル スキャンを引き起こす可能性があります。ただし、他の式が決定論的である場合、 WHERE句は部分的に最適化できます。例えば:

SELECT * FROM t WHERE partial_key=5 AND some_column=RAND();

オプティマイザーがpartial_keyを使用して選択された行のセットを削減できる場合、 RAND()実行回数が少なくなり、不確実性が最適化に与える影響を軽減できます。

上記はMySQL関数呼び出しの最適化の詳細な説明です。MySQL関数呼び出しの最適化の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL 空間データストレージと関数
  • MySQL の日付型の単一行関数コードの詳細な説明
  • MySql の null 関数の使用の共有
  • MySQLの基本の共通機能
  • MySQL で sum 関数を使用する例のチュートリアル
  • MySQLの共通関数を使用してJSONを処理する方法
  • MySQLのDATE_ADDとADDDATE関数は、指定された時間間隔を日付に追加します。
  • MySQL関数の簡単な紹介

<<:  WeChatミニプログラムのすべてのページがログインされていることを確認する方法

>>:  CSS における zoom:1 属性の定義と機能

推薦する

VMware マルチノード環境を構成する方法

このチュートリアルでは CentOS 7 64 ビットを使用します。各仮想マシンに 2GB のメモリ...

12個のJavascriptテーブルコントロール(DataGrid)が整理されています

DataGrid コントロールの DataSource プロパティがデザイン時に設定されている場合、...

Vueプロジェクトウォッチで関数が繰り返しトリガーされる問題の解決

目次問題の説明:解決策1解決策2問題の説明:ページ A と B の 2 つがあり、各ページにはget...

Webstorm と Chrome を使用して Vue プロジェクトをデバッグする方法

目次序文1. 新しいVueプロジェクトを作成する2. WebStormの設定1. デバッガポートを設...

タブバーのいくつかの実装方法(推奨)

タブ: カテゴリ + 説明タグバー: カテゴリ => ユーザーに現在地と目的地を知らせる1. ...

ウェブページの画像の回転を実現するjs

この記事では、Webページの画像の回転を実現するためのjsの具体的なコードを参考までに共有します。具...

MySQL は低速クエリを可能にします (EXPLAIN SQL ステートメントの使用の概要)

今日、データベース操作はますますアプリケーション全体のパフォーマンスのボトルネックになりつつあり、こ...

モバイル端末のジャンプ問題を解決する(CSS遷移、ターゲット疑似クラス)

序文モバイル端末に触れたばかりの友人の多くは、クリックジャンプルーティング、特にVueルーティングを...

JavaScript で文字列を数値に変換する方法

目次1.parseInt(文字列、基数) 2. 数値() 3.parseFloat()主なメソッドは...

CSS変換ページめくりアニメーションレコードの実装

ページめくりの問題のシナリオBとCは同じページ(表と裏)にありますページをめくって A をカバーした...

Linux または Windows 環境での pytorch のインストールと検証 (runtimeerror 問題の解決)

1. pytorch公式サイトから対応するインストールファイルをダウンロードします。 https:...

CSS で中空効果を実装するサンプルコード

効果原理主にCSSグラデーションを使用して、切り取りを必要としない背景のくり抜きを実現します。クーポ...

フロントエンド開発者に何百万ドルもの価値をもたらす 10 のスキル

フロントエンド開発者が習得する必要のあるスキル。これらのスキルにより、フロントエンド開発者の価値は数...

iframe タグの使用方法の詳細な説明 (属性、透明度、適応高さ)

1. iframe の定義と使用法iframe 要素は、別のドキュメントを含むインライン フレーム...

MySQL 完全折りたたみクエリ正規マッチングの詳細な説明

概要前の章では、クエリのフィルター条件について学習しました。MySQL では、like % ワイルド...