web-dev-qa-db-ja.com

ディスク上に作成された一時テーブル:巨大です

大量の一時テーブルがディスクに書き込まれるという問題があります。私はこれを回避するために多くのことを試みましたが、運が悪く、本当にあきらめています。私はこの問題を解決するためにいくつかの専門知識が必要かもしれませんが。

私のマシンは4つのwordpressサイトに専用です。サーバーには8つのコアと64GBのRAMがあります。

Mysqltunnerを実行するたびに、このメッセージが表示されます

ディスク上に作成された一時テーブル:84%(ディスク上に3K /合計3K)

そしてその数は増え続けています。

PHPmyadminから私はこのメッセージに気づきました:

問題:並べ替えが多すぎると、一時テーブルが発生します。一時テーブルの平均:1分あたり1.24。この値は1時間あたり1未満である必要があります。

これが私の設定です

    [mysqld]
    log-error=/var/lib/mysql/server.ict-hardware.com.err
    default-storage-engine=InnoDB
    performance-schema=ON
    skip-name-resolve=1

    # MyISAM #
   key-buffer-size                = 110M
   myisam-recover                 = FORCE,BACKUP
   join_buffer_size               = 4M
   sort_buffer_size               = 4M

   # SAFETY #
   max-allowed-packet             = 16M
   max-connect-errors             = 1000000
   # CACHES AND LIMITS #
   tmp-table-size                 = 512M
   max-heap-table-size            = 512M
   query-cache-type               = 0
   query-cache-size               = 0
   max-connections                = 500
   thread-cache-size              = 100
   open-files-limit               = 65535
   table-definition-cache         = 8096
   table-open-cache               = 8096

   # INNODB #
   innodb-flush-method            = O_DIRECT
   innodb-log-files-in-group      = 2
   innodb-log-file-size           = 3075M
   innodb-flush-log-at-trx-commit = 1
   innodb-file-per-table          = 1
   innodb-buffer-pool-size        = 30G
   innodb_buffer_pool_instances   = 30

   # LOGGING #
   log-error                      = /var/lib/mysql/./mysql-error.log
   log-queries-not-using-indexes  = 1
   slow-query-log                 = 1
   slow-query-log-file            = /var/lib/mysql/./mysql-slow.log
   long_query_time                = 10

   max_allowed_packet=268435456
   open_files_limit=2048

いくつかの調査の後、1秒以上かかる2つのメインクエリがあることがわかりました

SELECT DISTINCT(wp_posts.post_parent) as ID
FROM wp_posts 
INNER JOIN wp_postmeta AS pf1
ON (wp_posts.ID = pf1.post_id) 
INNER JOIN wp_term_relationships
ON (wp_posts.ID = wp_term_relationships.object_id) 
WHERE wp_posts.post_type = "product_variation" 
AND pf1.meta_key IN ("attribute_pa_women-clothes")
AND pf1.meta_value IN ("s","") 
AND ( wp_posts.ID IN (
SELECT object_id
FROM wp_term_relationships
WHERE term_taxonomy_id IN ( 401 ) ) ) 
AND ( wp_posts.ID IN (
SELECT post_id
FROM wp_postmeta
WHERE meta_key LIKE "attribute_pa_%"
GROUP BY post_id
HAVING COUNT( DISTINCT meta_key ) = 1 ) ) 
GROUP BY pf1.post_id 
HAVING COUNT(DISTINCT pf1.meta_key) = 1 
LIMIT 29999

そして

SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month 
FROM wp_posts 
WHERE post_type = 'attachment' 
ORDER BY post_date DESC

助けてください:)

ありがとう

1
kashalo

あなたは「パフォーマンスの問題からあなたの方法を調整することはできません」。だから、悪役を探して修正しましょう。

_long_query_time_を1に変更します。1日待ちます。次に_pt-query-digest_を実行します。

詳細: http://mysql.rjweb.org/doc.php/mysql_analysis#slow_queries_and_slowlog

頻繁または長時間実行されているクエリは、slowlogに表示されます。それらの最初のカップルを見てみましょう。

可能性が高い候補はpostmetaです: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta

編集後

最初のクエリ:

IN ( SELECT ... )は悪名高いほど非効率的です。 _JOIN .. ON_に変更します。

上記のインデックスリンクに示されているように、インデックスを変更します。

_LIMIT 29999_は現実的ですか?大幅に下げることをお勧めします。

2番目のクエリ:

_INDEX(post_type, post_date)
_
1
Rick James

my.cnfのやるべきこと:

[mysqld]セクションで、システムのデフォルトが機能するようにREMOVEします。

sort_buffer_size
join_buffer_size
    both of your lines for
max_allowed_packet
   one of your two
open_files_limit

残り

open_files_limit = 30000 # would be reasonable

行を追加

innodb_buffer_pool_instances = 8 # to smooth contention across 8 parts of RAM

SESSIONで、処理に256Mのmax_allowed_pa​​cketが必要な場合、

SET @max_allowed_packet=268452456 # and follow with
LOAD DATA LOCAL INFILE ..... (to avoid rollbacks. adjust up to 1G)

my.cnf/iniのように、256Mを使用してセッション制限を設定することはできません。

0
Wilson Hauck