A碑文
最近、同社はいくつかのクエリ機能のリストを見つける長い時間の後の行に新しい機能を追加するために投影します。その理由は、旧関数インタフェースを使用するための新しい機能であり、これらの古いテーブル5,6および書き込みに関連したSQLクエリインターフェイスは、SQL文、全表スキャンの実行中に、インデックスのMySQLの失敗、その結果、標準化されていません。したがって、クエリデータの問題を最適化し、家に帰るために残すことを同僚に何かを最適化するためのもともと責任著者の手に落ちます。オンライン情報アクセスSQLの最適化後の作者は成功し、グローバルな視点から、この時に、問題を解決し、記録し、関連するMySQLのクエリの最適化技法をまとめたものです。
第二に、最適化のアイデア
スロークエリデータは、質問に書かれているSQL文を意味するものではありません。まず、我々は問題の原因を見つける必要がある「右の薬を。」MySQLの最適化のアイデアを示すフローチャートを使用します。
これ以上の言葉は明確のような理由から、さまざまな照会遅いデータが得られ、図から見られないことができます:クラッシュする原因MySQLサーバへの高い同時アクセスのリードに時間のこの期間内にキャッシュの無効化を、問題のSQL文を書き、MySQLサーバ問題のパラメータ、ハードウェア構成の制限MySQLのサービスのパフォーマンスの問題。
第三に、MySQLサーバのステータスを表示値が実行されています
システムの同時要求の数は高くなく、クエリが遅い場合は、このステップは、直接ステップをチューニングするSQL文を省略することができます。
コマンドを実行します。
show status
結果が掲載されていないリターンあまりにも多くの結果、以来。その中でも、結果が戻って、我々は、「クエリ」の値に「Threadsconnected」と「Threadsrunning」、すなわち、問い合わせの数、スレッドの接続と実行中のスレッドの数を集中します。
私たちは、状態値を実行しているモニターのMySQLサーバに次のスクリプトを実行することができます
#!/bin/bash
while true
do
mysqladmin -uroot -p"密码" ext | awk '/Queries/{q=$4}/Threads_connected/{c=$4}/Threads_running/{r=$4}END{printf("%d %d %d\n",q,c,r)}' >> status.txt
sleep 1
done
コンテンツにstatus.txtを得るために、24時間のスクリプトを実行し、第二のMySQLサービスあたりの要求の再数は== == awkにして算出します
awk '{q=$1-last;last=$1}{printf("%d %d %d\n",q,$2,$3)}' status.txt
生成されたExcelのグラフに計算されたコンテンツのコピーは、定期的にデータを観察しました。
周期的な変化は、キャッシュ無効化ポリシーを変更するための図解釈を必要としているとして、データを観察した場合。
例えば:
[3,6,9]前記キャッシュミスの時間と間隔の値が取得した乱数、キャッシュの有効期限は、これにより、メモリ消費量の一部を保存する、分散します。
キャッシュ失敗への要求の分割部分のピークにアクセスする場合、他の部分は、このように圧力MySQLサーバーを削減、MySQLデータベースへのアクセスです。
第四に、最適化されたSQL文を取得する必要があります
4.1方法1:実行中のスレッドを見ます
コマンドを実行します。
show processlist
リターン結果:
mysql> show processlist;
+----+------+-----------+------+---------+------+----------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+------+---------+------+----------+------------------+
| 9 | root | localhost | test | Query | 0 | starting | show processlist |
+----+------+-----------+------+---------+------+----------+------------------+
1 row in set (0.00 sec)
返された結果から、我々は、スレッドは、コマンド/ SQL文と実行時間を実行するかを理解することができます。実用的なアプリケーションでは、クエリがNレコードが存在することになる結果を返します。
その中で、国家の戻り値は、裁判官が良いか悪いパフォーマンスの鍵となり、その値が表示されますが、次の行は、SQL文を最適化する必要があります。
Converting HEAP to MyISAM # 查询结果太大时,把结果放到磁盘,严重
Create tmp table #创建临时表,严重
Copying to tmp table on disk #把内存临时表复制到磁盘,严重
locked #被其他查询锁住,严重
loggin slow query #记录慢查询
Sorting result #排序
4.2方法:スロークエリログをオンにします
【のmysqld]内の構成ファイルのmy.cnfに二つのパラメータの次の行を追加します。
slow_query_log = 1
slow_query_log_file=/var/lib/mysql/slow-query.log
long_query_time = 2
log_queries_not_using_indexes = 1
ここで、slowquerylog = 1は、スロークエリを回すことを示している。slowquerylogfileはスロークエリログの格納場所を表し; = 2 longquerytimeは、ログの前にクエリが> = 2秒であることを示し; = 1つの記録logqueriesnotusing_indexesは、インデックスのSQL文を使用していません。
注:パスslowquerylog_fileは、単に書くことはできませんそれ以外の場合は、指定されたディレクトリに書き込まれたMySQLサーバのログファイルへのアクセス権を持っていない可能性があります。推奨パスが真上にコピー。
ファイルの保存変更した後、MySQLサービスを再起動します。これは、は/ var / libに/ mysqlの/ディレクトリにスローquery.logのログファイルを作成します。MySQLサーバに接続すると、コンフィギュレーションを表示するには、以下のコマンドを実行することができます。
show variables like 'slow_query%';
show variables like 'long_query_time';
スロークエリログをテストします。
mysql> select sleep(2);
+----------+
| sleep(2) |
+----------+
| 0 |
+----------+
1 row in set (2.00 sec)
スロークエリログファイルを開きます。
[root@localhost mysql]# vim /var/lib/mysql/slow-query.log
/usr/sbin/mysqld, Version: 5.7.19-log (MySQL Community Server (GPL)). started with:
Tcp port: 0 Unix socket: /var/lib/mysql/mysql.sock
Time Id Command Argument
# Time: 2017-10-05T04:39:11.408964Z
# User@Host: root[root] @ localhost [] Id: 3
# Query_time: 2.001395 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
use test;
SET timestamp=1507178351;
select sleep(2);
私たちは、記録されるSQL文を実行するためにわずか2秒を見ることができます。
スロークエリログに記録遅いSQLクエリ情報が、しかし、集中的かつビューに難しいのログレコード。したがって、我々は、SQLツールを使用してフィルタリングする必要があります。
MySQLはmysqldumpslow提供 ログ分析のためのツールを。私たちは、関連する使用状況を表示するmysqldumpslow --helpコマンドを使用することができます。
次のように一般的なパラメータは次のとおりです。
-s:排序方式,后边接着如下参数
c:访问次数
l:锁定时间
r:返回记录
t:查询时间
al:平均锁定时间
ar:平均返回记录书
at:平均查询时间
-t:返回前面多少条的数据
-g:翻遍搭配一个正则表达式,大小写不敏感
ケース:
获取返回记录集最多的10个sql
mysqldumpslow -s r -t 10 /var/lib/mysql/slow-query.log
获取访问次数最多的10个sql
mysqldumpslow -s c -t 10 /var/lib/mysql/slow-query.log
获取按照时间排序的前10条里面含有左连接的查询语句
mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/slow-query.log
SQL文のV.分析
5.1方法1:説明
問題のあるSQLをスクリーニング、我々はMySQLのビューSQL実行計画のケース(アソシエーションテーブル、テーブルのクエリー配列、インデックスの使用など)を説明供給を使用することができます。
使用法:
explain select * from category;
リターン結果:
mysql> explain select * from category;
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | category | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
+----+-------------+----------+------------+------+---------------+------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
フィールドは説明した:1)ID:クエリー配列番号を選択します。同じIDを、上から下に実行順序、IDの異なる、より大きな値Id高い優先度、実行される最初
2)SELECT_TYPE:操作のクエリデータ型、次のような値です。
- シンプル:簡単なクエリは、サブクエリまたは共用体が含まれていません
- プライマリー:値のための複雑なサブクエリ、最も外側のクエリ・マークが含まれています
- サブクエリ:または場所を選択備えるサブクエリ、この値は標識されています
- 派生:リストに含まれるサブクエリは、この値からマークされ、MySQLの意志を再帰的にこれらのサブクエリ、一時テーブルでの結果
- 組合:組合の後に第2の選択表示された場合は、その値をマークしました。外層からサブクエリに含ま組合が標識されている場合に得られる選択
- ユニオン結果:労働組合のテーブルからの結果は、選択します
3)テーブル:テーブルの行データを表示
4)パーティション:パーティションの試合
5)タイプ:接続テーブルのタイプ、その値、高次の末尾に以下の特性:
- システムテーブルはシステムテーブルに対応する行のみを有します
- CONST:索引を介して一旦データマッチングの一つだけの行を見つけます
- でeq_ref:ユニークインデックススキャン、各インデックス・キー、テーブルの試合で1つのレコードのみのため。一般的に主キーまたは一意索引スキャンで使用されます
- 参考文献:非一意のインデックススキャンは、別の値に一致するすべての行を返します。A =、<または>演算子インデックス付け列
- 範囲:行のみを選択するためにインデックスを使用して、与えられた範囲の行を検索します。一般的に、>、<状況の間で使用されます
- インデックス:インデックスツリーのみトラバーサル
- ALL:全表スキャン、最悪のパフォーマンス
注:最初の5例は、理想的な状況のインデックスの使用状況です。通常、少なくともレベル範囲に最適化され、それがrefを最適化するのが最善です
6)possible_keys:MySQLは、行を見つけるために、この表で使用するインデックスを示しています。値がNULLの場合は、パフォーマンスを向上させるためにインデックスを付けることができ、インデックスの記述を使用していません
7)キー:表示されたインデックスのMySQLが実際に使用。nullの場合、インデックスのクエリを使用していません
8)key_lenに:インデックスで使用されるバイト数は、クエリで使用されるインデックスは、列の長さによって計算されます。精度の損失なしに、長さより短く、より良いディスプレイは、インデックスフィールドの最大の長さではなく、実際の長さであります
9)参考文献:表示するテーブルのフィールドテーブルに関連付けられたインデックスフィールド
10)行:選択テーブル統計および場合、所望の記録又は読み出しを見つけるために必要な行数、値が小さいほど、よりよいの概算
11)濾過:行の数の割合がより良く、読み取られた行の数を示す結果が返された値
12)エクストラ:他の列に表示されるが、追加の情報が非常に重要であり、不適切な含まれ、一般的な値は次の通りです:
- filesortレコードを使用する:MySQLのではなく、テーブル内のインデックス順を読んで、外部データの順序インデックスを用いて説明します。値の出現は、最適化すべきであるSQL
- 一時的な使用:クエリ結果をソートする際の中間結果を保持するため、一時テーブルの使用を、MySQLは一時テーブルを使用します。でクエリグループをソートし、グループ化することで順番に共通します。値の出現は、最適化すべきであるSQL
- データアクセス表の行を避けるために、カバーされたインデックスを使用して、対応する選択操作によって表される、良好な効率:インデックスを使用して
- これはラインwhere句を制限します。どこを使用して
- バッファを使用して参加する:使用の接続キャッシュは、
- 異なる:最初の複数のラインの現在の行の組み合わせの一致、停止検索を見つけます
注:2つの値の出現する前に、SQL文を最適化する必要があります。
5.2第二の方法:プロファイリング
SQLステートメントは、(実行の各ステップのコスト)のリソースを消費しているの詳細を学ぶためにプロファイリングコマンドを使用します。
5.2.1プロフィールを表示ケースオープン
select @@profiling;
リターン結果:
mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
| 0 |
+-------------+
1 row in set, 1 warning (0.00 sec)
0ターン1はを表し、オフ表します
5.2.2プロファイルを有効にします
set profiling = 1;
リターン結果:
mysql> set profiling = 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select @@profiling;
+-------------+
| @@profiling |
+-------------+
| 1 |
+-------------+
1 row in set, 1 warning (0.00 sec)
接続が閉じられた後、プロファイリング状態は自動的に閉状態に設定されています。
実行されたSQL 5.2.3のリストを見ます
show profiles;
リターン結果:
mysql> show profiles;
+----------+------------+------------------------------+
| Query_ID | Duration | Query |
+----------+------------+------------------------------+
| 1 | 0.00062925 | select @@profiling |
| 2 | 0.00094150 | show tables |
| 3 | 0.00119125 | show databases |
| 4 | 0.00029750 | SELECT DATABASE() |
| 5 | 0.00025975 | show databases |
| 6 | 0.00023050 | show tables |
| 7 | 0.00042000 | show tables |
| 8 | 0.00260675 | desc role |
| 9 | 0.00074900 | select name,is_key from role |
+----------+------------+------------------------------+
9 rows in set, 1 warning (0.00 sec)
コマンドが実行される前に、SQLステートメントのみで追加録音を実行する必要があります。
5.2.4クエリID指定された実行の詳細
show profile for query Query_ID;
リターン結果:
mysql> show profile for query 9;
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000207 |
| checking permissions | 0.000010 |
| Opening tables | 0.000042 |
| init | 0.000050 |
| System lock | 0.000012 |
| optimizing | 0.000003 |
| statistics | 0.000011 |
| preparing | 0.000011 |
| executing | 0.000002 |
| Sending data | 0.000362 |
| end | 0.000006 |
| query end | 0.000006 |
| closing tables | 0.000006 |
| freeing items | 0.000011 |
| cleaning up | 0.000013 |
+----------------------+----------+
15 rows in set, 1 warning (0.00 sec)
各行は状態変更処理、並びにそれらの期間です。国家のこのコラムやショーPROCESSLISTの状況は同じです。このため、注目は、上記と同様の点で最適化される必要があります。
5.2.5 CPU、ブロックIOおよび他の情報を取得します
show profile block io,cpu for query Query_ID;
show profile cpu,block io,memory,swaps,context switches,source for query Query_ID;
show profile all for query Query_ID;
第六に、最適化手法
主に説明するために、デザインを使用してクエリの最適化、インデックスとテーブル構造インチ
6.1クエリ最適化
1)SELECT *を避け、必要とされるどのようなデータは、対応するフィールドが照会します。
2)小さなテーブル駆動大型テーブル、すなわち、小さなデータセットは、大規模なデータセットを駆動します。例えば:A、B 2テーブル、例えば、2つのテーブルidフィールドを関連付けることによって。
Bは、以下のテーブルデータテーブル存在における最適化の組よりなる場合、表B、表Aの配列を確認し、確認するために、二つのテーブルが実行されるで使用
select * from A where id in (select id from B)
Aが少ないBよりもテーブルデータセットのテーブルである場合には、最適化が存在;使用はEXISTS、二つのテーブル表A、表Bの配列を確認し、確認するために行われます
select * from A where exists (select 1 from B where B.id = A.id)
3)いくつかの場合において、接続は、の使用が加わるので、MySQLはメモリに一時テーブルを作成しなくなり、代わりにサブクエリを使用することができます。
4)適切に関連付けられたテーブルを低減、冗長フィールドを追加しました。
5)インデックスの使用の合理化は、()について説明します。以下のような:filesortレコードを避けるために、グループ、インデックスフィールドをソートします。詳細:MySQLのデータ構造へのインデックスと最適化の在庫
6.2を使用するインデックス
インデックス・シーンの使用のために6.2.1
1)主キーは自動的に一意のインデックスを作成します
クエリの条件としてしばしば2)フィールド
フィールド3)他のテーブルに関連付けられているクエリ
4)クエリフィールドを並べ替えます
5)統計クエリまたはグループフィールド
使用インデックスには適していません6.2.2シーン
1)頻繁に更新フィールド
より少ないフィールド条件2)
3)テーブルのレコードを過ぎます
4)通常のテーブルのCRUD
5)差フィールド値または少し高い再現性
6.2.3インデックスの作成と使用の原則
1)単一テーブルのクエリ:クエリの列は、列に索引を作成します
2)マルチテーブルクエリは:あなたが参加去ったとき、インデックスは右のテーブルの関連フィールドに追加し、右に参加するとき、インデックスは、左フィールド相関表に追加します
3)操作を実行しない(計算、型変換)列インデックス
4)インデックス列を使用しないでください!=、<>等しくありません
5)列インデックスが空ではない、としない使用がnullであるか、ヌル分析ありません
6)インデックスフィールドは、文字列型は、クエリ条件が、単一引用符」の値を増加させる自動変換を避けるために底を入力することです
上記の原則に反して、インデックスの故障の原因となり、特定の状況では、それを表示するコマンドを説明する必要があります
6.2.4障害の指標ケース
インデックス作成と使用の原則に違反することに加えて、次のような状況では、インデックスの故障につながることができます。
1)ファジー問い合わせは、%で始まるとき
2)のような、使用時や:フィールド1(非インデックス付き)またはフィールド2(インデックス)故障インデックスを引き起こすであろう。
3)最初のインデックス列を使用せずに、複合インデックスを使用する場合。
例えば、複合指標として、B、Cのフィールドのインデックス(A、B、C)。
適切なデータ型データベースのテーブル構造6.3デザインを選択6.3.1
1)使用して、最小のデータ型のデータを格納することが可能です
2)単純なデータ型の使用を。シンプルよりもmysqlのプロセスのint varchar型のタイプ
整数型intなど3)メイク使用TINYINT、SMALLINT、MEDIUMINTはなく、
ヌルは、空間の4つのバイトを占有するため4)、NOT NULLを使用することが可能な限りフィールドを定義します
5)テキストタイプの使用を最小限に抑え、非サブテーブルを使用する際に考慮すべきことはお勧めできません
6)日時のタイムスタンプの代わりに使用してみてください
7)推奨20内に、あまりにも多くの単一のテーブルのフィールドがありません。
分割表6.3.2
データベース内のデータが非常に大きい場合には、クエリの最適化計画は遅いクエリの問題を解決することはできませんデータが小さくなるように、私たちはこのように、クエリの効率を向上させ、各テーブル、分割テーブルを考慮することができます。
1)垂直スプリット:テーブル内の列の複数の異なるテーブルに分離されます。ユーザテーブル内のフィールドの一部が頻繁にアクセスされ、例えば、テーブル内のこれらのフィールドは、追加フィールドの数は、他のテーブルで使用されていません。場合は、挿入データ、二つのテーブルのデータの一貫性を確保するためにトランザクションを使用しました。
2)水平スプリット:行の分割。例えば、ユーザテーブル、ユーザID、10以上のアクセスに対するユーザID、表0-9にユーザ10へのユーザデータの均一な分布。場合は、このルールに従って、クエリデータを検索します。
6.3.3個別の読み取りと書き込み
データベースのための通常の状況下では、「読み書きが少ない」です。換言すれば、データを読み取るための大部分の操作の多数ため、データベースの圧力が生じ。私たちは、データベースクラスタソリューションを使用するライブラリとしてメインのライブラリを使用することができ、データを書き込むための責任であり、他のライブラリのライブラリから、データを読み込むための責任があります。これは、データベースへのアクセスへの圧力を緩和します。
七、サーバーのチューニングパラメータ
7.1メモリ関連
sortbuffersizeソートメモリサイズのバッファ
接続joinbuffersizeを使用してバッファサイズ
完全なテーブルは、割り当てられたバッファサイズreadbuffersizeをスキャンする場合
7.2 IO関連
Innodblogfile_sizeトランザクションログのサイズ
トランザクションログのInnodblogfilesingroup数
Innodblogbuffer_sizeトランザクションログバッファサイズ
Innodbflushlogattrx_commitトランザクションリフレッシュ戦略をログに記録し、次のように、その値は次のとおりです。
0:ディスクに毎秒ログキャッシュ、およびフラッシュログを書き込みます
1:各トランザクションでのログ書き込みキャッシュに提示され、ディスクへのフラッシュログ
2:トランザクションがコミットされるたびに、キャッシュに書き込まれた実行ログデータは、ディスクへの第二のフラッシュログごとに1回実行さ
7.3セキュリティ関連
expirelogsdaysは、日数の自動クリーンアップを指定ビンログ
maxallowedpacket MySQLは、受信したパケットのサイズを制御することができます
skipnameresolve無効にDNSルックアップ
READ_ONLY非スーパーユーザー権限の書き込み権限を禁止
skipslavestartレベルあなたは、スレーブ自動回復を使用します
その他7.4
制御MAX_CONNECTIONSによって許可される接続の最大数
一時テーブルのサイズをtmptablesize
最大メモリサイズのテーブルをmaxheaptable_size
私は、MySQLサーバのチューニング、パフォーマンスの結果にこれらのパラメータを使用して、特定の詳細を紹介していなかった、記事の最後に情報を参照するか、そうでない場合はBaiduのしてください。
八、ハードウェアの購入とパラメータ最適化
ハードウェアの性能に直接MySQLデータベースの性能を決定します。ハードウェアのパフォーマンスのボトルネックは、直接操作するデータとMySQLデータベースの効率を決定します。
ソフトウェア開発者のプログラマーとして、私たちは、あなたが理解できるようなハードウェアを最適化するためのコンテンツ最適化ソフトウェアに注力します
8.1メモリ関連
IOメモリより高速なハードドライブの多くよりも、あなたがシステムのバッファ容量を増やすことができ、データはディスクIOを減らすためにメモリ内に長くとどまります
8.2ディスクI / O関連の
1)IOPSを持ち上げる時間の少なくとも数百または数千を得る、SSDまたはSSD PCLEデバイスを使用して
2)同時に取得カード・アレイ、キャッシュBBUモジュールと、有意にIOPSを向上させることができます
3)可能な限りRAID-10の選択、RAID-5の代わりとして
8.3設定関連CUP
次のようにBIOSセットアップサーバでは、調整:
1)、パフォーマンスパーワット最適化(DAPC)モードを選択し、最大CPUのパフォーマンスを再生
2)閉じるC1E C米国およびその他のオプションを、CPU効率を高めます
3)メモリ周波数(周波数メモリ)選択した最大パフォーマンス