序文 この記事では主に、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 最適化シリーズ: フレーム読み込み
目次JavaScriptでは、通常、次のコードのようにクラスを簡単に定義できます。 var サンプル...
数日前に仕事を始めて、Mysql をインストールしたところ、開くことができました。今日、会社に行った...
tcpdump は、ネットワークの問題のトラブルシューティングに効果的に役立つ、柔軟で強力なパケット...
私はいつも、なぜMySQLデータベースのtimestampタイムゾーンの問題を無視できるのか疑問に思...
これは実際には IE の公式ドキュメントではありません。他の人が実践を通じて開発した IE6 のデフ...
問題の説明ESXI で Windows にワークステーションをインストールした後、内部の仮想マシンは...
遅いクエリをチェックすると、時間が正しくなく、システム時間とちょうど 8 時間異なっていることがわか...
Bash 初期化ファイル対話型ログインシェル次の場合にはログイン シェルを取得できます。ローカル端末...
MongoDBインストールYumを使用してインストールすることを選択する1. repoファイルを作成...
この記事では、参考までにMySQLの無料インストール構成チュートリアルを紹介します。具体的な内容は次...
Linux システム管理者にとって、サービスがポートに正しくバインドされているか、またはポートをリッ...
最近、分散型およびビッグデータ技術について学ぶために、いくつかの仮想マシンに取り組んでいます。まず、...
ページの説明: メインページ: 名前 —> shishengzuotanhuichaxun ...
目次テーマを動的に変更する最初の方法: 動的コンポーネント2番目の方法はルーティング分離です要約する...
Server 2016 のリモート デスクトップ接続のデフォルト数は 2 ユーザーです。2 人以上...