ヒント:
1. 非効率なステートメントを検出するにはどうすればよいですか?
MySQLでは、起動パラメータに--log-slow-queries=[ファイル名]を設定することで、実行時間がlong_query_time(デフォルトは10秒)を超えるSQL文を指定したログファイルに記録できます。次のように、起動設定ファイルで長いクエリ時間を変更することもできます。
# 長いクエリ時間を 8 秒に設定します
long_query_time=8
2. テーブルのインデックスをクエリするにはどうすればよいですか?
次のような SHOW INDEX ステートメントを使用できます。
SHOW INDEX FROM [テーブル名]
3. 特定のステートメントのインデックスの使用状況をクエリするにはどうすればよいですか?
EXPLAIN ステートメントを使用すると、特定の SELECT ステートメントのインデックスの使用状況を確認できます。 UPDATE または DELETE ステートメントの場合は、最初に SELECT ステートメントに変換する必要があります。
4. INNODB エンジンの内容をエラー ログ ファイルにエクスポートするにはどうすればよいですか?
SHOW INNODB STATUS コマンドを使用すると、現在のプロセス、トランザクション、外部キー エラー、デッドロックなど、INNODB エンジンに関する多くの有用な情報を表示できます。問題やその他の統計。この情報をログ ファイルに記録できるようにするにはどうすればよいですか?次のステートメントを使用して innodb_monitor テーブルを作成している限り、MySQL は 15 秒ごとにシステムをエラー ログ ファイルに書き込みます。
CREATE TABLE innodb_monitor (a INT) ENGINE=INNODB;
エラー ログ ファイルにエクスポートする必要がなくなった場合は、 、削除するだけです このテーブルは次のとおりです:
DROP TABLE innodb_monitor;
巨大なログ ファイルを定期的に削除するにはどうすればよいですか?
起動設定ファイルにログの有効期限を設定するだけです:
expired_logs_days=10
注:
1. インデックスに注目します
。以下では、SQL ステートメントの最適化プロセスを説明するための例としてテーブル TSK_TASK を使用します。 TSK_TASK テーブルは、システム監視タスクを保存するために使用されます。ID
: 主キー、
MON_TIME: 構築されたタスク
のステータス、SYS_HIER_INFO.ID で確立された外部キー関係。
注: MySQL は、外部キーのインデックスを自動的に作成します。この最適化プロセス中に、これらの自動的に作成された外部キーのインデックスが SQL ステートメントの効率に不必要な干渉を引き起こすことが判明しました。特別な注意が必要です。
まず、ログ ファイルで次のステートメントの実行が比較的遅く、10 秒以上かかっていることがわかりました。
# Query_time: 18 Lock_time: 0 Rows_sent: 295 Rows_examined: 88143
select * from TSK_TASK WHERE STATUS_ID = 1064 and MON_TIME >= ' 2007-11 -22' and MON_TIME < '2007-11-23';
88143 件のレコードの中から条件を満たす 295 件のレコードを見つける必要があることがわかり、当然時間がかかります。 EXPLAIN ステートメントをすぐに使用して、インデックスの使用状況を確認します。
+----+-------------+----------+------+- ---------
テーブルの
タイプ | キー長 |
----------+------+-----------
1 | TSK_TASK_ID_TO_SYS_HIER_INFO を使用
| +---------------+----------+------+----------- --
そこにあることがわかります
。使用可能なインデックスは 2 つあります: FK_task_status_id_TO_SYS_HIER_INFO、TSK_TASK_KEY_MON_TIME、STATUS_ID の外部キー インデックスはステートメントが最終的に実行されるときに使用されます。
TSK_TASK テーブルのインデックスをもう一度見てみましょう:
+----------+-------------------------- -- --------
| キー名 |
+----------+----------+----- -- ---------------
|
TSK_TASK_ID_TO_SYS_STATUS_ID
|
-------------------------Oracle またはその他のリレーショナル データベースでは、WHERE 条件の選択において、インデックス内のフィールドの順序が重要な役割を果たします。インデックス。フィールドの順序を調整し、最後に STATUS_ID を付けて、再度 EXPLAIN を実行します。
EXPLAIN
select * from TSK_TASK WHERE MON_TIME >= '2007-11-22' and MON_TIME < '2007-11-23' and STATUS_ID = 1064;
効果はありませんが、MySQL はシステムによって作成された STATUS_ID 外部キー インデックスを引き続き使用します。
注意深く分析した結果、MySQL はインデックスの選択において、カーディナリティ属性 (つまり、インデックス内の一意の値の数) が非常に重要な役割を果たしているようです。一意の値の数が少ないインデックスが選択されます。ステートメント全体のインデックスとしてインデックスに含まれます。
このステートメントでは、FK_task_status_id_TO_SYS_HIER_INFO をインデックスとして使用し、TSK_TASK テーブルに何日もデータが保存される場合、スキャンされるレコードの数が多くなり、速度が遅くなります。利用可能な最適化ソリューションがいくつかあります。
1 日にあまり多くのタスクがない場合は、インデックス FK_task_status_id_TO_SYS_HIER_INFO を削除します。その後、MySQL はインデックス TSK_TASK_KEY_MON_TIME を使用し、その日のデータ内の STATUS_ID 1064 のレコードをスキャンします。これは遅くありません。 ;
1 日に多くのタスクがある場合は、インデックス FK_task_status_id_TO_SYS_HIER_INFO と TSK_TASK_KEY_MON_TIME を削除してから、STATUS_ID、MON_TIME の結合インデックスを作成する必要があります。これは間違いなく非常に効率的です。
したがって、パフォーマンス効率の大幅な低下を避けるために、多数のレコードを持つテーブルには外部キーを使用しないことをお勧めします。
2. 各テーブルのレコード数を制御するようにしてください。
テーブル内のレコード数が多いと、インデックスのメンテナンスに時間がかかり、システムに大きな混乱が生じます。システムの通常の動作による干渉。
時間の経過とともにデータ量が増加し続けるテーブルについては、バックグラウンド サービス プログラムを使用して、リアルタイム データと履歴データを時間に基づいて区別し、リアルタイム テーブルのデータを履歴テーブルに定期的に移動することで制御できます。リアルタイム テーブルのレコード数が増加し、クエリのパフォーマンスと運用効率が向上します。ただし、各移動の時間は、通常のプログラムのデータ書き込みに影響を与えないように十分に短くする必要があることに注意してください。時間がかかりすぎると、デッドロックの問題が発生する可能性があります。
3. データのハッシュ (パーティション) 戦略:
顧客の数が一定の規模に達すると、単一のデータベースではより高い同時アクセスをサポートできなくなります。この時点で、顧客データを複数のデータベースにハッシュ (パーティション) することを検討できます。負荷を分散し、システム全体のパフォーマンスと効率を向上させます。