web-dev-qa-db-ja.com

インデックスなしで実行された結合:5568

Mysqlの最適化を実行しようとしました。昨日のCPU使用率は100%でした。私はmysqltunerで最適化しようとしていますが、今回はmysqltuner警告を出しました。

トラフィックの多いdbがあります。 1日に500-600接続。多分もっと。

どうすれば修正できますか?

[!!]インデックスなしで実行された結合:5568

使用されるキーバッファー:18.2%(97M使用/ 536Mキャッシュ)

InnoDBログファイルサイズ/ InnoDBバッファープールサイズ(12.5%)の比率:256.0M * 2/4.0Gは25%に等しい

InnoDB書き込みログの効率:70.64%(3619ヒット/合計5123)

Centos 6 8GB RAMと4プロセッサ

hdd: https://Pastebin.com/AnFdUHp6

更新しました:

my.cnf: https://Pastebin.com/g7DbmZ2T

更新:

mysqltuner: https://Pastebin.com/HBdSjxaj

グローバル変数: https://Pastebin.com/xTzu2PGM

しかし、CPU使用率は依然として100%でした。

2
Tota1907

Joins performed without indexes: 91。これは、おそらくパフォーマンスの最大の原因です。

データベースに、複数のテーブルのデータを結合するSQLクエリで使用される列の適切なインデックスがありません。

つまり、MySQLはインデックスデータだけを調べるのではなく、テーブル全体をスキャンして、クエリキーに一致する行を取得する必要があります。

したがって、SQLクエリを調べて、結合で使用されるテーブル/列に適切なインデックスを追加する必要があります。

3
Tero Kilkanen

構成には少なくとも2つの問題があります。

  • 割り当て超過max_connections。最高の接続使用率は4で、440の接続を割り当てたため、メモリの過剰消費が発生しました(各接続は18.5 Mを割り当て、8Gメモリを使用する440接続を掛けたものです)。 max_connections 20まで下げ、接続の使用状況を定期的に監視します。
  • 割り当て超過innodb_buffer_pool_size。データセットは254.3Mで、4Gを割り当てました。それを1Gに減らし、少なくとも2日間再起動せずにデータベースが負荷の下で実行されているときに後で確認します。リセットもinnodb_buffer_pool_instancesから1。

メモリの過剰割り当て(12.6GがMySQLに割り当てられている+ 1.3Gその他のプロセスメモリ> 8Gのシステムメモリ)により、システムがスワップスラッシングになり、CPU使用率が高くなった可能性があります。

2
AlexD

適合しない最初の答えについて申し訳ありません-私は明らかに昨日疲れすぎてあなたの質問を誤解しました。

接続プールを使用すると、アプリケーションの全体的なパフォーマンスが向上しますが、おそらく最初に実行する他の方法があります。

MysqlTunerは、設定する有効なオプションを提案します。

query_cache_size (=0)
query_cache_type (=0)
query_cache_limit (> 1M, or use smaller result sets)
join_buffer_size (> 1.0M, or always use indexes with JOINs)
innodb_log_file_size should be (=528M) if possible, so InnoDB total log files size equals to 25% of buffer pool size.
innodb_buffer_pool_instances(=4)

また、mysqld.logが定期的にローテーションされていることを確認し、そこで警告/エラーを確認してください。あなたはそれを削除してmysqldを再起動することから始めて、次にそこからどんなエラー/警告がそこに出力されるかを見るかもしれません。

innodb_buffer_pool_sizeを1G(1073741824)およびinnodb_buffer_pool_instancesを1に下げると、パフォーマンスに悪影響があるかどうかをテストできます。 mysqltunerによると、バッファには254.3Mのデータしかないため、拡張するのに十分なスペースがあります。

@ tero-kilkanenの提案も一見の価値があるかもしれません。 19000件のクエリのうち、一致するインデックスが欠けているのは58件しかなかったので、これによってパフォーマンスが大幅に向上するとは思いません。ただし、インデックスの健全性と含まれているキーを確認してください。

MysqldがインストールされているRAMの容量よりも多く使用する可能性があるという警告を取り除くには、max_connectionsを20から30までの適切な数値に下げる必要があります。アプリケーションの稼働時間は最大で4ですmysqld。
mysqldによって割り当てられるメモリの最大量は、max_connections(440)に接続ごとに割り当てられたキャッシュ(大抵はsort_buffer_sizeといくつかの小さいキャッシュ)を乗算し、グローバルバッファ(つまりinnodb_buffer_pool_size)を使用します。接続ごとに18.5MBはあまり聞こえませんが(実際はそうではありません)、440倍すると、8GBになります。

アプリケーションは主に読み取りステートメント(99%)を使用するため、アプリケーション側にキャッシュを追加すると、データベース全体の負荷が軽減され、フロントエンド側のパフォーマンスが著しく向上する可能性があります。
ほとんど変更されない定期的に照会される値(たとえば、フロントエンドユーザーテーブル)がキャッシュされる可能性があります。次に、学生/親ユーザーとその権限を編集するときにキャッシュを無効にすることができます。

それでも問題が発生する場合は、mysqltunerを実行する前に、mysqldおよびアプリケーションを長時間実行してください。より正確な使用プロファイルにより、1〜3日でより適切な提案が得られます。

My.cnf [mysqld]セクションで考慮すべき提案1秒あたりのレート= RPS

Open_files_limitを使用して最初の行を削除し(my.cnfには2つあります)、インスタンスでデフォルトが機能するようにinnodb_open_files = 800000を指定した行のみを削除します。

following could be change or ADD line to my.cnf

thread_cache_size=100  # for CAP of 100 per V5.7 refman to reduce threads_created
query_cache_type=0  # for NO query cache to conserve CPU cycles
query_cache_size=0  # from 1M to conserve RAM for more useful purpose
innodb_io_capacity=15000  # from 200 to use more of SSD IOPS capacity
sort_buffer_size=2M  # from 6M to conserve RAM per CONNECTION
read_buffer_size=128K  # from 1M to reduce handler_read_next RPS
join_buffer_size=256K  # from 2M per table join OPS per CONNECTION
table_open_cache=10000  # from 524288 for a practical LIMIT
table_definition_cache=1000  # from 2000 since you have less than 100 tables today
open_files_limit=65536  # from 1049026 million for a practical LIMIT
0
Wilson Hauck