以前、ある開発者が私のところに来て、アプリケーション内の特定の関数クエリが以前よりも大幅に遅くなったと言いました。開発者に提供を依頼しました 遅い SQL ステートメントについては、対応する MySQL データベースの実行計画を確認したところ、実行計画が間違っていることがわかりました。最初の反応は、テーブルの 1 つの統計情報が不正確であり、それが実行の原因でした。 SQL文の計画が間違っていると、効率的なSQLクエリから遅いSQLになってしまいます。問題を特定した後は、当然のことながら再度分析して情報を収集します。このとき、分析テーブル上のすべての選択が突然スタックし、結果が返されなくなったことに気付きました。その後、アプリケーションがさまざまなアラーム メッセージを爆発的に表示しました。
分析操作はスレーブ ライブラリで実行され、影響を受けるのは基本的に選択クエリでした。したがって、ここでシミュレートされるのはクエリ操作です。
シミュレーション テーブルの作成
mysql> select * from t_test_1; +----+--------+-------+--------+ | id | name | name2 | status | +----+--------+-------+--------+ | 1 | name1 | 1001 | 0 | | 2 | name1 | 1002 | 1 | | 3 | name1 | 1003 | 1 | | 4 | name1 | 1004 | 0 | | 5 | name1 | 1005 | 1 | | 6 | name1 | 1006 | 0 | | 7 | name1 | 1007 | 2 | | 8 | name1 | 1008 | 0 | | 9 | name1 | 1009 | 1 | | 10 | name10 | 1001 | 0 | +----+--------+-------+--------+ 10 rows in set (0.00 sec)复制代码
遅いクエリをシミュレートします。ここではデータ量が十分ではないため、代わりにスリープが使用されます。 session1: 遅いクエリをシミュレートします
mysql> select sleep(1000) from t_test_1;复制代码
session2: テーブル統計の収集をシミュレートします
mysql> analyze table t_test_1;复制代码
session3: 分析コマンドの実行をシミュレートした後、t_test_1 テーブルで選択クエリを実行します
mysql> select * from t_test_1 where id=5;复制代码
session4: すべてのセッション情報をクエリ
mysql> select * from processlist order by time desc; +----+------+-----------+--------------------+---------+------+-------------------------+----------------------------------------------+ | ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO | +----+------+-----------+--------------------+---------+------+-------------------------+----------------------------------------------+ | 21 | root | localhost | testdb | Query | 242 | User sleep | select sleep(1000) from t_test_1 | | 23 | root | localhost | testdb | Query | 180 | Waiting for table flush | analyze table t_test_1 | | 24 | root | localhost | testdb | Query | 3 | Waiting for table flush | select * from t_test_1 where id=5 | | 22 | root | localhost | information_schema | Query | 0 | executing | select * from processlist order by time desc | +----+------+-----------+--------------------+---------+------+-------------------------+----------------------------------------------+ 4 rows in set (0.00 sec)复制代码
session4 で取得したすべてのセッション情報から、2 つのセッションのステータスが「テーブル フラッシュ待ち」であることがわかります。
MySQL データベースが FLUSH TABLES tbl_name、ALTER TABLE、RENAME TABLE、REPAIR TABLE、ANALYZE TABLE、または OPTIMIZE TABLE などの操作を実行するとき、メモリ テーブルを閉じてテーブルを再度開き、新しいテーブル構造をメモリにロードします。ただし、テーブルを閉じるには、テーブルに対するすべての操作 (選択、挿入、更新、テーブルのロックなど) が終了するまで待つ必要があるため、特に遅い選択が実行されている場合、テーブル分析コマンドは終了しません。
テーブルのフラッシュを待機する原因がわかったので、遅い SQL ステートメントの特定を開始できます。ここで、実行しているのは t_test_1 テーブルの収集であることがわかります。そのため、t_test_1 テーブルを含む遅いクエリをクエリする必要があり、実行時間は分析テーブル t_test_1 の実行時間よりも長くなります。
mysql> select * from processlist where info like '%t_test_1%' and time >=(select time from processlist where id=23) order by time desc; +----+------+-----------+--------+---------+------+-------------------------+----------------------------------+ | ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO | +----+------+-----------+--------+---------+------+-------------------------+----------------------------------+ | 21 | root | localhost | testdb | Query | 1187 | User sleep | select sleep(1000) from t_test_1 | | 23 | root | localhost | testdb | Query | 1125 | Waiting for table flush | analyze table t_test_1 | +----+------+-----------+--------+---------+------+-------------------------+----------------------------------+ 2 rows in set (0.37 sec)复制代码
上記の SQL ステートメントを使用すると、id=21 のセッションを簡単に見つけることができ、分析テーブル t_test_1 が停止してしまうため、セッション 21 を強制終了する必要があります。
mysql> kill 21; Query OK, 0 rows affected (0.01 sec) mysql> show full processlist; +----+------+-----------+--------------------+---------+------+----------+-----------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+--------------------+---------+------+----------+-----------------------+ | 22 | root | localhost | information_schema | Query | 0 | starting | show full processlist | | 23 | root | localhost | testdb | Sleep | 1205 | | NULL | | 24 | root | localhost | testdb | Sleep | 1028 | | NULL | +----+------+-----------+--------------------+---------+------+----------+-----------------------+ 3 rows in set (0.00 sec)复制代码
セッション、リフト失敗。
生産実行分析テーブルの提案 1. 実行前にテーブルのデータ量と所要時間を経験的に見積もるとともに、情報テーブルを収集する遅いSQLや長時間のトランザクションが実行されていないか確認してください。
2. ビジネスのピーク時に統計情報を収集するためにテーブル分析を実行することは避けてください。
#その他の関連する無料学習の推奨事項: mysql チュートリアル(ビデオ)
以上がMySQLデータベースが分析を実行して情報を収集しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。