web-dev-qa-db-ja.com

InnoDBメモリ/ CPUはMySQLでWordPressの最適化を使用します

私はDBAではないため、ここでいくつかの助けが必要です...トラフィックが高いWordPress EC2インスタンスでホストされているサイトです。クエリを最適化する新しいテーマコードで作業しています。しかし、今のところ、次のような低速のクエリ(ページの読み込みごとに3回呼び出される)が多いレガシーコードを保持する必要があります。

_# Time: 2017-08-25T17:10:29.753525Z
# User@Host: xxx[xxx] @ localhost []  Id:   442
# Query_time: 13.548223  Lock_time: 0.000147 Rows_sent: 6  Rows_examined: 188232
SET timestamp=1503681029;
SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1  AND (
  wp_term_relationships.term_taxonomy_id IN (3)
) AND wp_posts.post_type = 'post' AND ((wp_posts.post_status = 'publish')) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 6;
/usr/sbin/mysqld, Version: 5.7.19-0ubuntu0.16.04.1-log ((Ubuntu)). started with:
Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
_

これらは私が設定で使用している値です

_default-storage-engine = InnoDB
key_buffer_size         = 32M
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
myisam-recover-options  = BACKUP
max_connections        = 1000
query_cache_type        = 0
query_cache_limit       = 0
query_cache_size        = 0
sort_buffer_size        = 4M
join_buffer_size        = 4M
tmp_table_size = 1G
max_heap_table_size = 1G
table_open_cache = 512M
table_definition-cache = 1024
thread-cache-size              = 50
innodb-flush-method            = O_DIRECT
innodb-log-files-in-group      = 1
innodb-log-file-size           = 1500M
innodb-log-buffer-size         = 8M
innodb-flush-log-at-trx-commit = 1
innodb-file-per-table          = 1
innodb-buffer-pool-size        = 12G
innodb-buffer-pool-instances   = 12
innodb-buffer-pool-dump-at-shutdown = 1
innodb-buffer-pool-load-at-startup = 1
innodb_flush_log_at_trx_commit = 2
_

そして「mysqltuner.pl」の出力

_ >>  MySQLTuner 1.7.2 - Major Hayden <[email protected]>
 >>  Bug reports, feature requests, and downloads at http://mysqltuner.com/
 >>  Run with '--help' for additional options and output filtering

[--] Skipped version check for MySQLTuner script
Please enter your MySQL administrative login: root
Please enter your MySQL administrative password: [OK] Currently running supported MySQL version 5.7.19-0ubuntu0.16.04.1-log
[OK] Operating on 64-bit architecture

-------- Log file Recommendations ------------------------------------------------------------------
[--] Log file: /var/log/mysql/error.log(0B)
[OK] Log file /var/log/mysql/error.log exists
[OK] Log file /var/log/mysql/error.log is readable.
[!!] Log file /var/log/mysql/error.log is empty
[OK] Log file /var/log/mysql/error.log is smaller than 32 Mb
[OK] /var/log/mysql/error.log doesn't contain any warning.
[OK] /var/log/mysql/error.log doesn't contain any error.
[--] 0 start(s) detected in /var/log/mysql/error.log
[--] 0 shutdown(s) detected in /var/log/mysql/error.log

-------- Storage Engine Statistics -----------------------------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MEMORY +MRG_MYISAM +MyISAM +PERFORMANCE_SCHEMA 
[--] Data in InnoDB tables: 1G (Tables: 68)
[OK] Total fragmented tables: 0

-------- Security Recommendations ------------------------------------------------------------------
[OK] There are no anonymous accounts for any database users
[!!] User 'debian-sys-maint@localhost' has no password set.
[!!] There is no basic password file list!

-------- CVE Security Recommendations --------------------------------------------------------------
[--] Skipped due to --cvefile option undefined

-------- Performance Metrics -----------------------------------------------------------------------
[--] Up for: 20h 12m 2s (6M q [93.845 qps], 301K conn, TX: 8G, RX: 930M)
[--] Reads / Writes: 95% / 5%
[--] Binary logging is disabled
[--] Physical Memory     : 31.4G
[--] Max MySQL memory    : 21.4G
[--] Other process memory: 1.0G
[--] Total buffers: 13.0G global + 8.6M per thread (1000 max threads)
[--] P_S Max memory usage: 72B
[--] Galera GCache Max memory usage: 0B
[OK] Maximum reached memory usage: 13.3G (42.24% of installed RAM)
[OK] Maximum possible memory usage: 21.4G (68.11% of installed RAM)
[OK] Overall possible memory usage with other process is compatible with memory available
[OK] Slow queries: 0% (0/6M)
[OK] Highest usage of available connections: 2% (28/1000)
[OK] Aborted connections: 0.00%  (4/301157)
[!!] name resolution is active : a reverse name resolution is made for each new connection and can reduce performance
[OK] Query cache is disabled by default due to mutex contention on multiprocessor machines.
[OK] Sorts requiring temporary tables: 0% (69 temp sorts / 1M sorts)
[OK] No joins without indexes
[!!] Temporary tables created on disk: 77% (871K on disk / 1M total)
[OK] Thread cache hit rate: 99% (28 created / 301K connections)
[OK] Table cache hit rate: 99% (1K open / 1K opened)
[OK] Open file limit used: 0% (61/1M)
[OK] Table locks acquired immediately: 100% (151 immediate / 151 locks)

-------- Performance schema ------------------------------------------------------------------------
[--] Memory used by P_S: 72B
[--] Sys schema is installed.

-------- ThreadPool Metrics ------------------------------------------------------------------------
[--] ThreadPool stat is disabled.

-------- MyISAM Metrics ----------------------------------------------------------------------------
[!!] Key buffer used: 18.3% (6M used / 33M cache)
[OK] Key buffer size / total MyISAM indexes: 32.0M/43.0K
[!!] Read Key buffer hit rate: 92.7% (96 cached / 7 reads)

-------- InnoDB Metrics ----------------------------------------------------------------------------
[--] InnoDB is enabled.
[--] InnoDB Thread Concurrency: 0
[OK] InnoDB File per table is activated
[OK] InnoDB buffer pool / data size: 12.0G/1.7G
[OK] InnoDB log file size / InnoDB Buffer pool size: 1.5G * 2/12.0G should be equal 25%
[OK] InnoDB buffer pool instances: 12
[--] Number of InnoDB Buffer Pool Chunk : 96 for 12 Buffer Pool Instance(s)
[OK] Innodb_buffer_pool_size aligned with Innodb_buffer_pool_chunk_size & Innodb_buffer_pool_instances
[OK] InnoDB Read buffer efficiency: 100.00% (16013769931 hits/ 16013822393 total)
[!!] InnoDB Write Log efficiency: 18.62% (55219 hits/ 296557 total)
[OK] InnoDB log waits: 0.00% (0 waits / 241338 writes)

-------- AriaDB Metrics ----------------------------------------------------------------------------
[--] AriaDB is disabled.

-------- TokuDB Metrics ----------------------------------------------------------------------------
[--] TokuDB is disabled.

-------- XtraDB Metrics ----------------------------------------------------------------------------
[--] XtraDB is disabled.

-------- RocksDB Metrics ---------------------------------------------------------------------------
[--] RocksDB is disabled.

-------- Spider Metrics ----------------------------------------------------------------------------
[--] Spider is disabled.

-------- Connect Metrics ---------------------------------------------------------------------------
[--] Connect is disabled.

-------- Galera Metrics ----------------------------------------------------------------------------
[--] Galera is disabled.

-------- Replication Metrics -----------------------------------------------------------------------
[--] Galera Synchronous replication: NO
[--] No replication slave(s) for this server.
[--] This is a standalone server.

-------- Recommendations ---------------------------------------------------------------------------
General recommendations:
    Set up a Password for user with the following SQL statement ( SET PASSWORD FOR 'user'@'SpecificDNSorIp' = PASSWORD('secure_password'); )
    MySQL started within last 24 hours - recommendations may be inaccurate
    Configure your accounts with ip or subnets only, then update your configuration with skip-name-resolve=1
    Temporary table size is already large - reduce result set size
    Reduce your SELECT DISTINCT queries without LIMIT clauses
_

WordPress=でフックを使用して_SQL_CALC_FOUND_ROWS_をCOUNT(*)に置き換えましたが、クエリのパフォーマンスは向上しませんでした。

データベースの多くを最適化して、ページの読み込み速度を許容できる程度にすることができますが、CPUを消費しすぎて、メモリはほとんど消費しません。 30GB RAM 8コアボックスですが、3 GBのメモリと1-2コアしか使用していません。すべてのテーブルはInnoDBであり、より多くのメモリとより少ないCPUを使用したいので、 16GBのメモリと4つのコアを持つ小さなインスタンスに移行できます。

そこで、Perconaや同様のブログでオンラインで調査した内容と、stackoverflowの回答から、いくつか質問があります。

1)メモリ上に作成される一時テーブルを増やしますが、tmp_table_sizeとmax_heap_table_sizeを変更せずに32Mから1GBにすでに増やしています... 2)書き込みログの効率を上げます...どうすればよいですか? 3)パーティションテーブルは、結合/グループ化/並べ替えを改善しますか?

サーバーから確認する必要があるデータの詳細はありますか?私にお知らせください...

3
Ricardo BRGWeb

インデックスが必要なようですね

ALTER TABLE wp_posts ADD INDEX type_status_date_ndx (post_type,post_status,post_date);

クエリにはpost_typepost_statusに静的な値があり、post_dateにはすでに順序付けされている範囲があるため、このインデックスが必要です。

CPU使用率については、これをmy.cnfに追加してください(再起動が必要です)

innodb_read_io_threads=8
innodb_write_io_threads=8

詳細については、私の投稿 MySQLで複数のコアを使用することは可能ですか? および シングルスレッドデータベースとマルチスレッドデータベースのパフォーマンスについて を参照してください

3
RolandoMySQLDBA

max_connections = 250は、28 Highest usedに基づくと十分です。 thread_cache_size = 50は、20時間で301K接続をサポートし、オンデマンドでのスレッド作成を回避します。現在推奨されている制限は、ワークロードがこれだけ多くのスレッドを使用できる場合、thread_cache_sizeを100に制限することです。

1
Wilson Hauck

Innodb_log_buffer_size = 8Mから16Mに変更すると、稼働中の1時間ごとに、この単一のログファイルへの書き込み数が半分になります。

0
Wilson Hauck

さて、WP設計者には、さらにDBAスタッフが必要です。投稿の数が多い(つまり、WPの場合は多い)と思われますか?

クエリは

_SELECT  SQL_CALC_FOUND_ROWS wp_posts.ID
    FROM  wp_posts
    LEFT JOIN  wp_term_relationships
        ON (wp_posts.ID = wp_term_relationships.object_id)
    WHERE  1=1
      AND  ( wp_term_relationships.term_taxonomy_id IN (3) )
      AND  wp_posts.post_type = 'post'
      AND  ((wp_posts.post_status = 'publish'))
    GROUP BY  wp_posts.ID
    ORDER BY  wp_posts.post_date DESC
    LIMIT  0, 6;
_

_SELECT  SQL_CALC_FOUND_ROWS wp_posts.ID
    FROM  wp_posts
    WHERE  wp_posts.post_type = 'post'
      AND  wp_posts.post_status = 'publish'
    ORDER BY  wp_posts.post_date DESC
    LIMIT  0, 6;
_

ノート:

  • _wp_term_relationships_はLEFTを介して接続されており、そのリストからのフィールドは結果セットにないため、最終的なリストには影響しません。
  • JOINを取り除くと、_GROUP BY_は不要になります。
  • 次に、「カバーする」INDEX(post_type, post_status, post_date, ID)を追加します。 _SQL_CALC_FOUND_ROWS_を削除すると、このインデックスにより、すべての行を収集する必要なくLIMITに到達できます。

_SQL_CALC_FOUND_ROWS_を取り除くことでさらに高速化することができますが、「nnn行が不足しています」と表示されなくなります。 (はい、それはスピードアップするはずです上記のことをしています。)

16013769931は、わずか20時間の膨大な数のヒットです。

これらは高すぎます:

_tmp_table_size = 1G          -- 100M
max_heap_table_size = 1G     -- 100M
table_open_cache = 512M      -- This is entries, not bytes! --> 200
_

また、buffer_poolは必要以上に大きいため、次のように変更できます。

_innodb_buffer_pool_size = 2500M
_

次に、16GBの画像に縮小しても問題ありません。また、CPUの減少が害を及ぼすことはほとんどありません。 (MySQLは単一の接続に複数のコアを使用しません。)

パーティショニング-いいえ。

ログの効率-おそらく問題ではありません。

並列処理接続内は過大評価されています。接続数が多い場合、複数のコアが使用されています。 I/Oバウンドの場合、CPUの並列処理は無駄になります。 (I/Oバウンドではありません。)データ(など)を分割および再結合するオーバーヘッドは、オーバーヘッドを追加します。

MySQLは常に複数のconnectionsを実行して、単一のCPUでも共有できます。 (OSが共有を処理します。)

調整パラメータの別の分析が必要な場合は、 http://mysql.rjweb.org/doc.php/mysql_analysis を参照してください。

MySQLに関するその他のヒント: http://mysql.rjweb.org/doc.php/ricksrots

0
Rick James