[MySQLの] SQLの最適化

免責事項:この記事はブロガーオリジナル記事ですが、許可ブロガーなく再生してはなりません。https://blog.csdn.net/wrs120/article/details/80716574

1.最適化されたプロセス

しかし、通常、我々は通常、次のいずれかの手順のために、説明するまでもないでしょう。

  1. mysqlのに問題があることを検出しました
  2. スロークエリログをオンにし、そのような2秒以上として設定されたしきい値は、解析し、遅いSQLで、.explain +遅いSQLをそれをつかみます
  3. 内部のMySQLサーバショープロフィールSQLクエリ実行の詳細と文のサイクル
  4. SQLデータベースサーバパラメータのチューニング

次の手順は、各プレゼンテーションのために行われます

2.スロークエリログの設定

デフォルトのMySQLのスロークエリログがオフになっています。

  • ビューのステータス:SHOW VARIABLES LIKE '%slow_query_log%';OFFはスロークエリログが無効になって表します
- 一時的なターン: `設定グローバルslow_query_log = 1; '(現在のデータベース、MySQLの再起動失敗した場合にのみ有効) - 永続的に開いている:my.cnfのファイルが変更、[mysqldを]ノードのパラメータを追加または変更します。
show_query_log=1
slow_query_log_file=var/lib/mysql/xxx-slow.log
(指定慢查询日志文件的存放路径,系统默认给一个缺省的文件hostname-slow.log)
  • ビューのしきい値:何秒遅い回数 SHOW VARIABLES LIKE'long_query_time';
  • しきい値を設定
set global long_query_time=3;

或在my.cnf的[mysqld]节点下配置:

long_query_time=2;
log_output=FILE

  実行時間が等しいlong_query_timeいいです、と記録されません場合は
  、あなたが再接続やセッションを開いたりすることができ、設定した後、何の変化も見られないことがありSHOW GLOBAL VARIABLES LIKE '%slow_query_log%';

3.最適化の原則

3.1は、大規模なテーブル小さなテーブルを駆動することはありません

既存の二つの表のAとB:

:Aが存在するよりも使用において、テーブルデータセットテーブルデータセットBよりも大きい場合に

select * from A where id in (select id from B)
等价于:
select id from B
select * from A where A.id = B.id

Aは優れと、テーブルのデータセットを設定したテーブルデータB未満である場合に存在します。

select * from A where exists (select 1 from B where B.id = A.id)
等价于
select * from A
select * from B where B.id = A.id

選択... mytableは存在するから(サブクエリ)

  • 存在する:いくつかの条件が検証されるサブクエリ、主にデータのクエリは、データが検証結果に基づいて、メインクエリ結果を保存されているかどうかを決定する(真/偽)
  • (サブクエリ)の存在のみTRUEまたはFALSEを返しますので、サブクエリは、select *だけでなく、1を選択するか、選択
    「は任意の値」、公式のリストは無視されることを言った実際の実装を選択し、違いはありません
  • 実際の実装プロセスでは、サブクエリを最適化ではなく、一つ一つのコントラストの我々の理解されて存在しています

キーワードの最適化により、3.2順序

  • ORDER BY句、使用filesortレコードのソートを回避するために、道のインデックスの並べ替えを使用してみてください

    • MySQLは2つのfilesortレコードのソートとインデックス、インデックス、インデックス自体をスキャンMySQLの注文の完了を指すインデックス高い効率、より少ない効率的な方法filesortレコードをサポート
    • インデックスのケースを使用することによりソート順:1.oreder @ほとんどは、インデックスの最前線を残したことで、@ 2ここで、左端の最前線インデックスを満たすために結合句の条件によって句と注文。
    • しかし、一つのこと、filesortレコードを使用して2つ以上の一貫性のないソートフィールド、照合、使用がある場合
      ここで説明する絵を書きます
  • 可能な限り最高の左プリフィックス索引に従って、インデックスに並べ替え操作を完了するために

  • そうでない場合には、インデックス列順に2つのアルゴリズムがありfilesortレコードによって:デュアル選別(ソーティング前デュアルMySQL4.1を用いて、すなわち、連動ディスクをスキャンは、データが最終的に得られる、と読み出し行ポインタORDERBYカラム、バッファーを並べ替え、その後、ディスクは2、私はOを\、時間がかかる)であったとき。ディスクから他のフィールドを取り、単一のソートクエリは、スキャン順序付け、カラム緩衝液でそれらをソート順に従って、磁気ディスクから列を読み取る必要がある(後に列出力、高効率となるように第2の読み出しデータを回避する。したがって、ランダムI / OシーケンシャルI / Oに、それはメモリ内の各行ため保存、より多くのスペースを使用ししたがって、合計サイズがあってもよい容量sort_buffer抽出されたデータを超えると、それだけで、データ容量サイズsort_bufferをソートするために導くことができる[tmpファイルを作成し、複数組み合わせ]、得られた排気次いで、sort_buffer容量サイズを取り、次いで排液し、...時間は、I / O)、単一の未解決の問題が発生し、次のソリューションを使用します。

  • SELECT * FROMによって順序がタブーであるとき、すなわちフィールドへの不要なリターンを減らすために

  • Sort_buffer_size(改善された本は、MySQL、単一の並べ替えを使用することを決定することはできないが、セグメントの順序MySQLの少ないI / Oの数を減らすために

  • Max_length_for_sort_data増加(返された長さのすべてのフィールドは、このパラメータの最大値未満である場合、MySQLは、単一のソートを選択し、このパラメータを増やす使用改良されたアルゴリズムの確率を増加させるであろうが、あまりにも高く設定した場合、確率は、データsort_buffer_sizeの総容量を超え増加させ、高いディスクI / Oアクティビティと低いプロセッサ使用率の明らかな症状)


キーワードの最適化により、3.3グループ

  • ソート、グループ化の本質によって、最初のグループの後、インデックス構築の最高の左接頭辞に従ってください
  • インデックス列を使用しない場合は、sort_buffer_sizeおよびパラメータ設定を増やしmax_length_for_sort_data
  • 有する上、HAVINGを定義するつもりはない定義された条件で書くことができる場所

4. mysqldumpslowツール

  本番環境では、ログファイルが大きい、手動ログ解析、検索、分析mysqlのではなく、現実的な場合、MySQLは、ログ解析ツールのmysqldumpslowを提供します。

次のように一般的なツールは、以下のとおりです。

5.ショープロフィール

何5.1
  MySQLが提供していることを分析するために使用することができ、現在のセッションの文の実行中にリソース消費は、SQLの測定を調整するために使用することができる
MySQLサポートプロファイルの表示かどうかを確認するために5.2を
「プロファイリング」などの5.3ビューステータス表示変数;

  デフォルトではオフになって、そして最後の15回の実行結果を保ちます

; SET開くプロファイリングON 5.4 =
5.5は、SQL結果の実行を表示するには:表示 プロファイル。
ここで説明する絵を書きます

5.6診断SQL:ショープロファイルCPU、ブロックIOクエリのためのクエリID番号(表示プロファイル取得QUERY_ID)
ここで説明する絵を書きます
コンテンツパラメータ視聴することができます。

どのようなSQL文5.7は、問題の記事ことを示していますか?
stautsすると次の文は、問題があることを示しています:

  • MyISAMテーブルにHEAP変換:クエリ結果はディスクに移動するには大きすぎる、十分でないメモリであり、
  • TMP表を作成:一時テーブルを作成、削除、その後、一時テーブルにデータをコピー
  • ディスク上のテーブルをtmpにするためにコピーする:メモリの一時テーブルのコピーをディスクに、それは非常に危険です!
  • ロック:ロックアップ

6.グローバルクエリログ

オープンテスト環境でのみ、それは、本番環境で開いてはいけません

  • オープンコンフィギュレーション・ファイルを使用します。my.cnfファイルを変更します。
# 开启
general_log=1
#记录日志文件的路径
general_log_file=/path/logfile
# 输出格式
log_output=FILE
  • 開くためのコマンドを使用します。
# 开启
set general_log=1;
# 输出形式
set global log_output='TABLE';

  その後、SQL文を記述しているので、テーブルのMySQLライブラリをgeneral_logするために記録されます

  • ログファイルを表示します。mysql.general_logから*選択します。
    ここで説明する絵を書きます

  問題は、MySQLの実装である場合には、一定期間を表示され、それは時間を記録するので、あなたは、SQL文の実行時に問題を発見し、prifilesクエリ実行時間のSQL文を表示することができるように、焦点を当て、、、グローバルクエリログに表示することができます調査のは間違いありません


おすすめ

転載: blog.csdn.net/wrs120/article/details/80716574