序文 この記事では主に、SQL ステートメントの最適化の一般的な手順について説明します。これは、参考と学習のために共有されています。さっそく、詳細な紹介を見てみましょう。 1. show statusコマンドを使用して、さまざまなSQL文の実行頻度を把握する mysql クライアントが正常に接続された後、
# Com_xxx は、各 xxx ステートメントが実行される回数を示します。 mysql> 'Com_%' のようなステータスを表示します。 私たちは通常、次のような統計パラメータを重視します。
上記のパラメータは、すべてのストレージ エンジンのテーブル操作に対して累積されます。以下のパラメータは InnoDB 専用であり、蓄積アルゴリズムは若干異なります。
上記のパラメータにより、現在のデータベース アプリケーションが挿入更新を主としているのか、クエリ操作を主としているのか、また、さまざまな種類の SQL のおおよその実行比率を簡単に把握できます。更新操作の回数は、コミットまたはロールバックに関係なく累積される実行回数の回数です。 トランザクション アプリケーションの場合、 さらに、次のパラメータは、ユーザーがデータベースの基本的な状況を理解するのに役立ちます。
2. 実行効率の低いSQL文を定義する 1. 実行効率が低い SQL ステートメントを見つけるには、スロー クエリ ログを使用します。-- 2. スロークエリログは、クエリが完了した後にのみ記録されます。そのため、アプリケーションが実行効率の問題を反映している場合、スロークエリログでは問題を特定できません。show processlistコマンドを使用すると、スレッドの状態、テーブルがロックされているかどうかなど、現在のMySQLスレッドを表示できます。SQLの実行状況をリアルタイムで表示し、一部のテーブルロック操作を最適化できます。 3. 非効率的なSQLの実行計画をExplainで分析する テスト データベース アドレス: https://downloads.mysql.com/docs/sakila-db.zip (ローカル ダウンロード) 特定の電子メールで映画のコピーをレンタルするために支払われた合計金額をカウントするには、顧客テーブル customer と支払いテーブル payment を関連付け、amount フィールドに対して合計演算を実行する必要があります。対応する実行プランは次のとおりです。 mysql> explain select sum(amount) from customer a , payment b where a.customer_id= b.customer_id and a.email='[email protected]'\G ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル テーブル: パーティション: NULL タイプ: すべて 可能なキー: プライマリ キー: NULL キー長さ: NULL 参照: NULL 行数: 599 フィルター: 10.00 追加: where の使用 ************************** 2. 行 **************************** id: 1 選択タイプ: シンプル 表: b パーティション: NULL タイプ: ref 可能なキー: idx_fk_customer_id キー: idx_fk_customer_id キーの長さ: 2 参照: sakila.a.customer_id 行数: 26 フィルター: 100.00 追加: NULL セットに 2 行、警告 1 件 (0.00 秒)
1. mysql> explain select * from film where ratings > 9 \G ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル 表: フィルム パーティション: NULL タイプ: すべて 可能なキー: NULL キー: NULL キー長さ: NULL 参照: NULL 行数: 1000 フィルター: 33.33 追加: where の使用 セットに 1 行、警告 1 回 (0.01 秒) 2. mysql> フィルム\G のタイトル選択フォームの説明 ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル 表: フィルム パーティション: NULL タイプ: インデックス 可能なキー: NULL キー: idx_title キーの長さ: 767 参照: NULL 行数: 1000 フィルター: 100.00 追加: インデックスの使用 セットに 1 行、警告 1 件 (0.00 秒) 3. mysql> explain select * from payment where customer_id >= 300 and customer_id <= 350 \G ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル 表: 支払い パーティション: NULL タイプ: 範囲 可能なキー: idx_fk_customer_id キー: idx_fk_customer_id キーの長さ: 2 参照: NULL 行数: 1350 フィルター: 100.00 追加: インデックス条件の使用 セットに1行、警告1回(0.07秒) 4. mysql> 顧客ID = 350 \G の支払いから選択 * を説明します ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル 表: 支払い パーティション: NULL タイプ: ref 可能なキー: idx_fk_customer_id キー: idx_fk_customer_id キーの長さ: 2 参照: 定数 行数: 23 フィルター: 100.00 追加: NULL セットに 1 行、警告 1 回 (0.01 秒) インデックス mysql> explain select b.*, a.* from payment a,customer b where a.customer_id = b.customer_id \G ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル 表: b パーティション: NULL タイプ: すべて 可能なキー: プライマリ キー: NULL キー長さ: NULL 参照: NULL 行数: 599 フィルター: 100.00 追加: NULL ************************** 2. 行 **************************** id: 1 選択タイプ: シンプル テーブル: パーティション: NULL タイプ: ref 可能なキー: idx_fk_customer_id キー: idx_fk_customer_id キーの長さ: 2 参照: sakila.b.customer_id 行数: 26 フィルター: 100.00 追加: NULL セットに 2 行、警告 1 件 (0.00 秒) 5. mysql> explain select * from film a , film_text b where a.film_id = b.film_id \G ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル 表: b パーティション: NULL タイプ: すべて 可能なキー: プライマリ キー: NULL キー長さ: NULL 参照: NULL 行数: 1000 フィルター: 100.00 追加: NULL ************************** 2. 行 **************************** id: 1 選択タイプ: シンプル テーブル: パーティション: NULL タイプ: eq_ref 可能なキー: プライマリ キー: PRIMARY キーの長さ: 2 参照: sakila.b.film_id 行数: 1 フィルター: 100.00 追加: where の使用 セットに 2 行、警告 1 回 (0.03 秒) 6. mysql> テーブル test_const を作成します ( -> テストID int, -> テストコンテキストvarchar(10)、 -> 主キー (`test_id`)、 -> ); test_const に値(1,'hello')を挿入します。 select * from ( select * from test_const where test_id=1 ) a \G の説明 ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル テーブル: test_const パーティション: NULL 型: 定数 可能なキー: プライマリ キー: PRIMARY キーの長さ: 4 参照: 定数 行数: 1 フィルター: 100.00 追加: NULL セットに 1 行、警告 1 件 (0.00 秒) 7. mysql> 説明 1 から 1 をデュアルで選択する where 1 \G ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル テーブル: NULL パーティション: NULL タイプ: NULL 可能なキー: NULL キー: NULL キー長さ: NULL 参照: NULL 行: NULL フィルター: NULL 追加: テーブルは使用されません セットに 1 行、警告 1 件 (0.00 秒) タイプ type には、
警告を表示するコマンド explain を実行した後、 MySQL [sakila]> explain select sum(amount) from customer a , payment b where 1=1 and a.customer_id = b.customer_id and email = '[email protected]'\G ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル テーブル: パーティション: NULL タイプ: すべて 可能なキー: プライマリ キー: NULL キー長さ: NULL 参照: NULL 行数: 599 フィルター: 10.00 追加: where の使用 ************************** 2. 行 **************************** id: 1 選択タイプ: シンプル 表: b パーティション: NULL タイプ: ref 可能なキー: idx_fk_customer_id キー: idx_fk_customer_id キーの長さ: 2 参照: sakila.a.customer_id 行数: 26 フィルター: 100.00 追加: NULL セットに 2 行、警告 1 件 (0.00 秒) MySQL [sakila]> 警告を表示します。 +-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | レベル | コード | メッセージ | +-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | 注 | 1003 | /* select#1 */ select sum(`sakila`.`b`.`amount`) AS `sum(amount)` from `sakila`.`customer` `a` join `sakila`.`payment` `b` where ((`sakila`.`b`.`customer_id` = `sakila`.`a`.`customer_id`) and (`sakila`.`a`.`email` = '[email protected]')) | +-------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ セット内の 1 行 (0.00 秒) 警告メッセージ欄から、1=1 が常に成立する条件をオプティマイザが自動的に削除していることがわかります。つまり、SQL を書き換える際に、常に成立する条件をオプティマイザが自動的に削除していることになります。 explain コマンドはパーティションもサポートしています。 MySQL [sakila]> テーブル `customer_part` を作成します ( -> `customer_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, -> `store_id` tinyint(3) 符号なし NOT NULL, -> `first_name` varchar(45) NOT NULL, -> `last_name` varchar(45) NOT NULL, -> `email` varchar(50) デフォルト NULL, -> `address_id` smallint(5) 符号なし NOT NULL, -> `active` tinyint(1) NOT NULL デフォルト '1', -> `create_date` 日時 NOT NULL、 -> `last_update` タイムスタンプ NULL デフォルト CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP、 -> 主キー (`customer_id`) -> -> ) ハッシュによるパーティション (customer_id) パーティション 8; クエリは正常、影響を受けた行は 0 行 (0.06 秒) MySQL [sakila]> customer_part に挿入し、customer から * を選択します。 クエリは正常、599 行が影響を受けました (0.06 秒) レコード: 599 重複: 0 警告: 0 MySQL [sakila]> explain select * from customer_part where customer_id=130\G ************************** 1. 行 **************************** id: 1 選択タイプ: シンプル テーブル: customer_part パーティション: p2 型: 定数 可能なキー: プライマリ キー: PRIMARY キーの長さ: 2 参照: 定数 行数: 1 フィルター: 100.00 追加: NULL セット内の行は 1 行、警告は 1 件 (0.00 秒) sql によってアクセスされるパーティションは p2 であることがわかります。 4. performance_schema を通じて SQL パフォーマンスを分析する MySQLの古いバージョンでは、プロファイルを使用してSQLパフォーマンスを分析できます。私はバージョン5.7.18を使用していますが、これではプロファイルを使用できなくなりました。 5. トレースを使用して、オプティマイザーが実行プランを選択する方法を分析します。 MySQL 5.6 では、SQL ステートメントのトレース機能が提供されており、オプティマイザが実行プラン B ではなく実行プラン A を選択する理由や、オプティマイザの動作をより深く理解するのに役立ちます。 使用方法: まずトレースを開き、形式を json に設定し、トレースが使用できる最大メモリ サイズを設定して、デフォルトのメモリが小さすぎるために解析プロセス中に不完全な表示が発生するのを回避します。 MySQL [sakila]> optimizer_trace="enabled=on",end_markers_in_json=on; を設定します。 クエリは正常、影響を受けた行は 0 行 (0.00 秒) MySQL [sakila]> optimizer_trace_max_mem_size を 1000000 に設定します。 クエリは正常、影響を受けた行は 0 行 (0.00 秒) 次に、トレースする SQL ステートメントを実行します。たとえば、レンタル日 rental_date 2005-05-25 4:00:00 ~ 5:00:00 の間にレンタルされた、在庫番号 inventory_id 4466 の映画コピーのレコードをレンタル テーブル rental から検索するには、次のようにします。 mysql> 1=1 かつ rental_date >= '2005-05-25 04:00:00' かつ rental_date <= '2005-05-25 05:00:00' かつ inventory_id=4466 の場合、 rental から rental_id を選択します。 +-----------+ | レンタルID | +-----------+ | 39 | +-----------+ セット内の1行(0.06秒) MySQL [sakila]> information_schema.optimizer_trace\G から * を選択します ************************** 1. 行 **************************** クエリ: infomation_schema.optimizer_trace から * を選択します トレース: { 「ステップ」: [ ] /* 手順 */ } 最大メモリサイズを超えるバイト数: 0 権限不足: 0 セット内の 1 行 (0.00 秒) 6. 問題を特定し、適切な最適化策を講じる 上記の手順を実行すると、問題の原因を基本的に確認できます。このとき、状況に応じて適切な対策を講じることで、実行効率を最適化し、向上させることができます。 要約する 上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に少しでもお役に立てれば幸いです。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM をご愛顧いただき、ありがとうございます。 以下もご興味があるかもしれません:
|
<<: nginx を使用して同じドメイン名で複数の Vue プロジェクトをデプロイし、リバース プロキシを使用する方法
>>: CocosCreator ScrollView 最適化シリーズ: フレーム読み込み
1. コマンドの紹介gzip (GNU zip) コマンドは、ファイルの圧縮と解凍に使用されます。こ...
目次序文脱構築記号の役割使い方分割割り当ての適用アプリケーションの簡単な紹介JSONデータを抽出する...
前回の記事 https://www.jb51.net/article/154157.htm では、B...
最近 Linux をいじっていたので、nginx の新しいバージョンをインストールしたいと思いました...
1. Nginx ステータス監視Nginx には、Nginx の全体的なアクセス ステータスを監視す...
<br />原文: プログレッシブエンハンスメントを理解するアーロン・ガスタフソン翻訳:...
この記事では、ユーザーのログイン切り替えを実現するためのVueの具体的なコードを例として紹介します。...
目次前述のVARCHAR型VARCHAR適用可能な状況CHAR型テストVARCHAR(5)とVARC...
長い引用には blockquote を、短い引用には q を、参考文献には cite を使用します。...
この記事では、JD.comのカルーセル効果の表示を実現するためのJavaScriptの具体的なコード...
1. 背景多くのブログや記事を読みましたが、JVM のメモリ割り当て方法に関する包括的な記事は見つか...
1. はじめにLinux でファイルの作成時刻が見つかるかどうかは、ファイル システムの種類によって...
目次外部キーテーブルの関係を決定する方法テーブル関係を作成する方法1対多の関係 - 従業員テーブルと...
ウェブページに慣れていない友人の多くは私と同じように、HTML で要素、タグ、属性がどのように定義さ...
目次問題の説明フロントエンド制御(方法1)アイデアコードバックエンド制御(方法2)アイデアコード要約...