MySQL 最適化のケーススタディ

MySQL 最適化のケーススタディ

1. 背景

Youzan の各 OLTP データベース インスタンスには、実行時間が特定のしきい値を超える SQL ステートメントを強制終了するための sql-killer プロセスが設定されています。午後、開発者はSQLが強制終了したというエラーメッセージを受け取り、開発者のトラブルシューティングを支援しました。この記事ではこのケースを紹介します。

第2のシナリオ分析

テーブル構造:

テーブル `xxx_info` を作成します (

  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',

  `user_id` bigint(20) unsigned NOT NULL DEFAULT '0' ,

  `group_id` bigint(20) unsigned NOT NULL DEFAULT '0',

  `nick_name` varchar(30) NOT NULL DEFAULT '' COMMENT 'ニックネーム',

  `is_del` tinyint(5) NOT NULL DEFAULT '0' COMMENT '0: データが有効、1: データは論理的に削除されている',

  `created_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '作成時刻',

  `updated_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '変更時刻',

  主キー (`id`)、

  キー `idx_userid_groupid` (`user_id`,`group_id`)

) ENGINE=InnoDB AUTO_INCREMENT=1382032 デフォルトCHARSET=utf8mb4 ;

問題のSQLは次のとおりです

 xxx_info から id、name、status を選択します。user_id は (670039223,'373149878') であり、group_id は 1 であり、is_del は 0 です。

最初に SQL を見たとき、テーブル構造とインデックス user_id をチェックしました。これは数値型で、インデックスは正常でした。その後、手動実行プランでは idx_userid_groupid インデックスが使用されませんでした。

2つの異なるタイプのフィールドのuser_idが「暗黙の変換」を引き起こしている疑いがあります。パラメータ値を数値型または文字列に変更するか、user_id=数値型またはuser_id=文字列を使用して再度実行してください。

実行計画は正しいです。 2つの問題を解決する必要があります

では、(X,Y,Z) の user_id が異なるタイプである場合、なぜインデックスが通過しないのでしょうか?

実行プランをトレースするには、optimizer_trace を使用します。

セッション optimizer_trace を 'enabled=on' に設定します。

xxx_info から id、nick_name、is_del を選択します。user_id は (670039223,'373149878') であり、group_id は 1 であり、is_del は 0 です。

information_schema.optimizer_trace から * を選択します。

xxx_info から id、nick_name、is_del を選択します。user_id は (670039223,'373149878') であり、group_id は 1 であり、is_del は 0 です。

information_schema.optimizer_trace から * を選択します。

セッション optimizer_trace を 'enabled=off' に設定します。

2つのSQL文の実行計画を取得し、比較します。結果は次のようになります。

その結果を見て私は言った

https://bugs.mysql.com を調べましたが、関連する結果は見つかりませんでした。

コード内で異なるタイプの値を生成するにはどうすればよいでしょうか?

以下は開発者自身のテストです

現在の解決策は、開発者とコミュニケーションを取り、プログラム内でパラメータ型の一貫性チェックを実行し、すべてを int/long 型に変換するように依頼することです。

暗黙的な変換によってインデックスが失敗する一般的なシナリオに関する特別な注意

1 ここで、判定記号の左側は文字列で、右側は値です。

名前 = 123

2 複数テーブル結合条件のフィールドタイプが矛盾している(1と同様)

3 マルチテーブル結合条件の文字セットタイプが異なります。例えば

a テーブル order_no は utf8mb4、b テーブル order_no は utf8

興味のある友人は、さらにテストしたり、他のケースについて話し合ったりすることができます。

上記はMySQL最適化事例の詳細です。MySQL最適化事例の詳細については、123WORDPRESS.COMの他の関連記事にも注目してください。

以下もご興味があるかもしれません:
  • MySQLの大規模テーブル最適化ソリューションについての簡単な説明
  • MySQLのGROUP BYステートメントを最適化する方法
  • MySQLでANDとORを組み合わせる問題を解決する

<<:  FTP、FTPS、SFTPの違いについて簡単に説明します

>>:  Vue3 ベースのフルスクリーン ドラッグ アップロード コンポーネント

推薦する

CSS における要素の表示モード

CSS では、要素タグは、要素の表示モードの違いに応じて、インラインレベル要素とブロックレベル要素の...

DockerがMySQL構成実装プロセスを開始

目次実際の戦闘プロセスまずは主なコマンドと詳細を一つずつ説明しましょう起動が成功したかどうかを確認す...

CSS 向け SASS スタイル プログラミング ガイド

SASS を使用する開発者が増えるにつれて、SASS コードの数に注意する必要があります。 SASS...

JSはショッピングカート効果の単純な加算と減算を実装します

この記事の例では、ショッピングカートの簡単な追加と削除を実現するためのJSの具体的なコードを参考まで...

HTML ページに画像を挿入し、マップ インデックスを追加する方法の例

1. WEBでサポートされている画像形式: GIF: 256色を保存でき、透明色をサポートし、アニメ...

スパンの最小高さを定義するソリューションは効果がありません

span タグは HTML ウェブページを作成するときによく使用されますが、このタグの使い方がよくわ...

Vue フィルターの使用とタイムスタンプ変換の問題

目次1. 概念をすぐに認識する: 2. ローカルフィルター: 3. グローバルフィルター: 4. 拡...

MySQLトランザクションとMySQLログの詳細な説明

取引特性1. アトミック性: トランザクションの開始後、すべての操作が完了するか、まったく実行されな...

nginxリバースプロキシを使用するときに長時間接続を維持する方法

・【シーン説明】 HTTP1.1 以降、HTTP プロトコルは永続的な接続 (長い接続とも呼ばれます...

負荷分散と動的・静的分離を実現するNginx+Tomcatの原理の分析

1. Nginx ロードバランシングの実装原理1. Nginxはリバースプロキシを通じて負荷分散を実...

Windows オペレーティング システムでの Linux 仮想マシンのインストールと構成のチュートリアル

序文仕事では、Linux 環境で操作する必要があることがよくあります。ここでは、win10 システム...

Uniapp WeChatアプレット: キー障害の解決策

ユニアプリコード <テンプレート> <表示> <image v-for...

Linux システムによって報告される xfs_vm_releasepage 警告問題に対処する方法

問題の説明最近、いくつかのマシンで、一日のさまざまな時間に次の警告メッセージが表示されました。 3月...

Linux で文字列を整理するためのヒント

Linuxの操作では、ファイル内の文字列を置換したりカウントしたりすることが多いです。ここでまとめを...

JS関数の呼び出し、適用、バインドの超詳細な方法

目次JS 関数呼び出し、適用、バインドメソッド1. call() メソッド1. call() メソッ...