いくつかの場所で約50人のスタッフが使用するイントラネットアプリケーションを管理しています。アプリケーションはWindows Server 2008でホストされていますVM with 8GB RAMおよびMySQL(5.5)がIISと同じサーバーで実行されています。
スロークエリロギングを有効にしていて、特定のクエリが断続的に遅いことに気付きました。たとえば、一部のクエリは13秒かかるとログに記録していますが、マシン(またはサーバー)のMySQLクライアントで同じクエリを試行すると、高速(約0.1秒)です。
数週間前、私はmysqlcheck --auto-repair --optimize --all-databases
を実行しましたが、それは物事を助けるように見えました-クエリログはほとんど密集してはいませんでした。ただし、今週はさまざまなクエリが断続的に長時間かかるため、以前の状態に戻りました。
スロークエリログが今朝8.3秒かかると記録したクエリが1つあります。 CLIから5〜6回実行し、2回は〜2秒で、残りは0.2秒未満でした。
遅いクエリはすべてSELECT
ですが、1秒以上かかる非常に少数のINSERT
を目にしました。
すべてのテーブルはInnoDBです。 show variables
で示されるInnoDB変数は次のとおりです。
+---------------------------------+------------------------+ | Variable_name | Value | +---------------------------------+------------------------+ | have_innodb | YES | | ignore_builtin_innodb | OFF | | innodb_adaptive_flushing | ON | | innodb_adaptive_hash_index | ON | | innodb_additional_mem_pool_size | 27262976 | | innodb_autoextend_increment | 8 | | innodb_autoinc_lock_mode | 1 | | innodb_buffer_pool_instances | 1 | | innodb_buffer_pool_size | 2097152000 | | innodb_change_buffering | all | | innodb_checksums | ON | | innodb_commit_concurrency | 0 | | innodb_concurrency_tickets | 500 | | innodb_data_file_path | ibdata1:10M:autoextend | | innodb_data_home_dir | | | innodb_doublewrite | ON | | innodb_fast_shutdown | 1 | | innodb_file_format | Antelope | | innodb_file_format_check | ON | | innodb_file_format_max | Antelope | | innodb_file_per_table | OFF | | innodb_flush_log_at_trx_commit | 1 | | innodb_flush_method | | | innodb_force_load_corrupted | OFF | | innodb_force_recovery | 0 | | innodb_io_capacity | 2000 | | innodb_large_prefix | OFF | | innodb_lock_wait_timeout | 50 | | innodb_locks_unsafe_for_binlog | OFF | | innodb_log_buffer_size | 13631488 | | innodb_log_file_size | 652214272 | | innodb_log_files_in_group | 2 | | innodb_log_group_home_dir | .\ | | innodb_max_dirty_pages_pct | 75 | | innodb_max_purge_lag | 0 | | innodb_mirrored_log_groups | 1 | | innodb_old_blocks_pct | 37 | | innodb_old_blocks_time | 0 | | innodb_open_files | 300 | | innodb_purge_batch_size | 20 | | innodb_purge_threads | 0 | | innodb_random_read_ahead | OFF | | innodb_read_ahead_threshold | 56 | | innodb_read_io_threads | 64 | | innodb_replication_delay | 0 | | innodb_rollback_on_timeout | OFF | | innodb_rollback_segments | 128 | | innodb_spin_wait_delay | 6 | | innodb_stats_method | nulls_equal | | innodb_stats_on_metadata | ON | | innodb_stats_sample_pages | 8 | | innodb_strict_mode | OFF | | innodb_support_xa | ON | | innodb_sync_spin_loops | 30 | | innodb_table_locks | ON | | innodb_thread_concurrency | 0 | | innodb_thread_sleep_delay | 10000 | | innodb_use_native_aio | ON | | innodb_use_sys_malloc | ON | | innodb_version | 1.1.8 | | innodb_write_io_threads | 64 | +---------------------------------+------------------------+
この時点で何を見たり監視したりする必要がありますか? IISに対するメモリまたはディスクI/Oリソースの問題がある場合に専用データベースサーバーを取得する可能性を検討していますが、これは現実的ではない可能性があります。
商業上の機密保持の理由から、ここで特定のクエリを共有するのは気が進まないため、役に立たない可能性があります。
MySQL Tuner for Windowsを実行して、次の結果を得ました。
-8000 MBの物理メモリを想定-12286 MBのスワップスペースを想定-現在実行中のサポートされているMySQLバージョン5.5.24ログ-InnoDBエンジンがインストール済み-InnoDBテーブル内のデータ:575M(テーブル:194)-断片化されたテーブルの合計:194-すべてのデータベースユーザーにはパスワードが割り当てられています-最大:1d 7h 44m 38s(982K q [8.000 qps]、41K conn、TX:15G、RX:839M)-読み取り/書き込み:98%/ 2%-合計バッファー:2.6Gグローバル+ 960.0スレッドあたりK(最大400スレッド)-可能な最大メモリ使用量:3.0G(インストールされているRAMの38%)-遅いクエリ:1%(476/982K)-利用可能な接続の最大使用量:2%(7/400)-キーバッファーサイズ/合計MyISAMインデックス:641.0M/263.0K-キーバッファーヒット率:99%(2Mキャッシュ/ 7読み取り)-クエリキャッシュが無効-一時テーブルを必要とするソート:6%(5K一時ソート/ 102Kソート)-結合インデックスなしで実行:7320-ディスク上に作成された一時テーブル:38%(ディスク上で31K /合計84K)-スレッドキャッシュヒット率:99%(7作成/ 41K接続)-テーブルキャッシュヒット率:1%(155オープン/ 9K開いた)-使用されるオープンファイルの制限:0%(3/4K)-すぐに取得されるテーブルロック:100%(1M即時/ 1Mロック)-InnoDBデータサイズ/バッファプール:575.2M/2.0G-最適化テーブルを実行してテーブルを最適化し、パフォーマンスを向上-常にインデックスを使用するように結合クエリを調整します-調整を行う場合は、tmp_table_size/max_heap_table_sizeを等しくします-LIMIT句なしでSELECT DISTINCTクエリを減らします-ファイル記述子の制限を回避するためにtable_cacheを徐々に増やします-query_cache_size(> = 8M)-join_buffer_size(> 128.0K 、または常に結合でインデックスを使用する)-tmp_table_size(> 64M)-max_heap_table_size(> 16M)-table_cache(> 256)
月曜日の夜に、いくつかの構成変数を調整しました-join_buffer_size
、sort_buffer_size
、table_open_cache
。火曜日に、私は1時間かけてデータベース全体を調べ、結合で使用されているほとんどすべての列にインデックスを追加しました(いくつかを逃した可能性があります)。次に、アプリ内の変更をいくつか行った結果、a)クエリが改善され、b)(比較的)トラフィックの多いページでのクエリが減少しました。
変更前、月曜日の遅いクエリログには、1秒を超える474クエリがありました。火曜日のインデックス作成後のクエリは220秒で、1秒以上でした。木曜日までに、アプリの変更により、1秒を超えるクエリ数は110に減少しました。今朝、アプリのアップデートを行った後、今日はまた下がると予想しています。まだ、EXPLAINプロファイルが適切で、断続的に遅いクエリがいくつかあります。更新されたチューナーの出力は以下のとおりです。最新のアプリから適切なサイズのサンプルを収集した後、EXPLAINおよびSHOW CREATE TABLEを使用していくつかのサンプルクエリを提供します。
更新されたチューナー出力。今朝MySQLを再起動したので、元の投稿ほど多くのデータがありません。何らかの理由で、インデックスなしで実行された結合の数が出力されなくなりました...
これは今朝の午前8時47分に実行され、7.08秒かかりました。送信された行:10、検査された行:40。
MySQLクライアントで同じクエリを実行すると、0.06秒かかります。
SELECT ProjectFile.id, ProjectFile.project_id, ProjectFile.document_type,
ProjectFile.name, ProjectFile.project_file_type_id, ProjectFile.created,
ProjectFileType.id, ProjectFileType.name, ProjectFileType.is_archived
FROM db.project_files AS ProjectFile
LEFT JOIN db.project_file_types AS ProjectFileType
ON (ProjectFile.project_file_type_id = ProjectFileType.id)
WHERE ProjectFile.project_id = 19319
ORDER BY ProjectFileType.name ASC, ProjectFile.name ASC;
EXPLAIN出力:
*************************** 1. row *************************** id: 1 select_type: SIMPLE table: ProjectFile type: ref possible_keys: project_id key: project_id key_len: 5 ref: const rows: 10 Extra: Using where; Using temporary; Using filesort *************************** 2. row *************************** id: 1 select_type: SIMPLE table: ProjectFileType type: eq_ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: db.ProjectFile.project_file_type_id rows: 1 Extra:
それについてのコメントチューナーの出力:
Data in InnoDB tables: 575M (Tables: 194)
Total fragmented tables: 194
Run OPTIMIZE TABLE to defragment tables for better performance
allInnoDBテーブルがどのようにフラグメント化されているかに注意してください。それが実装方法の性質です。煩わしいしないOPTIMIZE
;それは実質的な利益を提供することはほとんどありません。
Joins performed without indexes: 7320
テーブルが小さい場合は関係ありません。重要なものは、log_queries_not_using_indexes
がなくてもスローログに表示されます。 (その設定はオフのままにします。スローログが乱雑になるだけです。)
Temporary tables created on disk: 38% (31K on disk / 84K total)
Slow queries: 1% (476/982K)
最悪のものを見てみましょう。 EXPLAIN
とSHOW CREATE TABLE
を入力してください。 long_query_time
は2以下をお勧めします。
チューナーからの最後の5アイテムは増加しないでください。
チューナーのコメントの残りの部分は合理的です。
次のステップ
Pt-query-digestから出力を取得し、最初の2つに加えてEXPLAIN
とSHOW CREATE TABLE
を見てみましょう。