web-dev-qa-db-ja.com

Amazon RDSの最適化-MySQLTunerの推奨事項/フィードバックと提案

私は現在、速度を上げるために継承したデータベースを最適化しようとしています。
サーバーはAmazon RDS db.m3.largeインスタンスです:

  • 2 VCPU
  • 7.5 GBメモリ
  • 500 GB HDD

私の現在の戦略は、次のことです。

  1. すべての開発データベースを削除し、それらを別のサーバーにプッシュする
  2. 以下の問題のあるテーブルのaggr_id列に一意のインデックスを追加します(生産を中断せずにこれを適切に行う方法は?)
  3. ロックを防ぐためにMyISAMテーブルをInnoDBに切り替えます(これを行うことの意味は何ですか?)

現在のアプローチやその他のアイデアに関するフィードバックを得るためにこの投稿を作成しています。私は決してDBAではなく、単なるWeb開発者です。事前のおかげで、あらゆるフィードバックを歓迎します。私は必ず返信し、回答を承認してください!この投稿は、得られた洞察と見つかったリソースを使用して編集します。

すべて同じ形式の問題の表がいくつかあります。

| xxxxx | CREATE TABLE `xxxxx` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `aggr_id` int(11) NOT NULL,
  `craft_id` int(11) NOT NULL,
  `task_year` smallint(8) unsigned NOT NULL,
  `hc1` mediumint(8) unsigned DEFAULT NULL,
  ......
  `hc365` mediumint(8) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`,`task_year`),
  KEY `IDX_AGGRLABORDAY` (`task_year`,`aggr_id`,`craft_id`)
) ENGINE=MyISAM AUTO_INCREMENT=50480037 DEFAULT CHARSET=latin1
/*!50500 PARTITION BY RANGE  COLUMNS(task_year)
(PARTITION p1 VALUES LESS THAN (2012) ENGINE = MyISAM,
 PARTITION p2 VALUES LESS THAN (2013) ENGINE = MyISAM,
 PARTITION p3 VALUES LESS THAN (2014) ENGINE = MyISAM,
 PARTITION p4 VALUES LESS THAN (2015) ENGINE = MyISAM,
 PARTITION p5 VALUES LESS THAN (2016) ENGINE = MyISAM,
 PARTITION p6 VALUES LESS THAN (2017) ENGINE = MyISAM,
 PARTITION p7 VALUES LESS THAN (9999) ENGINE = MyISAM) */

問題のあるクエリの説明は次のとおりです。

explain DELETE FROM xxxxx WHERE aggr_id = 3000010;
+----+-------------+---------------------------+------+---------------+------+---------+------+----------+-------------+
| id | select_type | table                     | type | possible_keys | key  | key_len | ref  | rows     | Extra       |
+----+-------------+---------------------------+------+---------------+------+---------+------+----------+-------------+
|  1 | SIMPLE      | xxxxx                     | ALL  | NULL          | NULL | NULL    | NULL | 46611048 | Using where |
+----+-------------+---------------------------+------+---------------+------+---------+------+----------+-------------+
1 row in set (0.05 sec)

以下はMySQLTunerの結果です。

[--] Assuming 7680 MB of physical memory
[!!] Assuming 0 MB of swap space (use --forceswap to specify)
[OK] Currently running supported MySQL version 5.6.21-log

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MRG_MYISAM 
[--] Data in MyISAM tables: 274G (Tables: 75)
[--] Data in PERFORMANCE_SCHEMA tables: 0B (Tables: 52)
[--] Data in InnoDB tables: 7G (Tables: 227)
[!!] Total fragmented tables: 35

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 107d 15h 56m 50s (110M q [11.901 qps], 3M conn, TX: 14149B, RX: 108B)
[--] Reads / Writes: 58% / 42%
[--] Total buffers: 5.4G global + 1.5M per thread (604 max threads)
[OK] Maximum possible memory usage: 6.2G (83% of installed RAM)
[OK] Slow queries: 0% (17K/110M)
[OK] Highest usage of available connections: 29% (177/604)
[OK] Key buffer size / total MyISAM indexes: 16.0M/49.6G
[OK] Key buffer hit rate: 99.4% (25B cached / 155M reads)
[!!] Query cache is disabled
[OK] Sorts requiring temporary tables: 2% (133K temp sorts / 6M sorts)
[!!] Temporary tables created on disk: 62% (7M on disk / 11M total)
[OK] Thread cache hit rate: 74% (945K created / 3M connections)
[!!] Table cache hit rate: 0% (1K open / 674K opened)
[OK] Open file limit used: 3% (2K/65K)
[!!] Table locks acquired immediately: 78%
[!!] InnoDB  buffer pool / data size: 5.3G/7.7G
[!!] InnoDB log waits: 1
-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    When making adjustments, make tmp_table_size/max_heap_table_size equal
    Reduce your SELECT DISTINCT queries without LIMIT clauses
    Increase table_open_cache gradually to avoid file descriptor limits
    Read this before increasing table_open_cache over 64: http://bit.ly/1mi7c4C
    Optimize queries and/or use InnoDB to reduce lock wait
Variables to adjust:
    query_cache_type (=1)
    tmp_table_size (> 16M)
    max_heap_table_size (> 16M)
    table_open_cache (> 2000)
    innodb_buffer_pool_size (>= 7G)
    innodb_log_buffer_size (>= 8M)
3
Ngz

(私はあなたのポイントを見て、これを書いています。行動を起こす前に最後まで読んでください。私は少しずつベストアンサーを「開発」します-いくつかのことを学んでほしいと思います。)

DELETE FROM xxxxx WHERE aggr_id = 3000010;

すべてのパーティションのすべての行をスキャンする必要があります。これは、チューニングに関係なく、多くのI/Oを実行する必要があることを意味します。

これが一般的なクエリの場合は、

INDEX(aggr_id)

さらに良いのは変化です

KEY `IDX_AGGRLABORDAY` (`task_year`,`aggr_id`,`craft_id`)

通常、「パーティションキー」(task_year)は、インデックスではなく、インデックスのendで終了するのが最適です。この場合は、単に削除することもできます。 task_yearの使用はすべて「プルーニング」用であり、KEYが引き継ぐことができます。 INDEXをDROPし、以下を1つのALTERに追加します。

KEY `IDX_AGGRLABORDAY` (`aggr_id`,`craft_id`)

注意:テーブルはしばらくロックされます。

オンラインのINDEX操作があるInnoDBに切り替える必要があります。

チューナーの提案は通常より悪いようです:

  • クエリキャッシュをオフのままにする
  • tmp_table_sizeおよびmax_heap_table_sizeを大きくしても、必ずしも有用ではありません
  • InnoDBとMyISAMを組み合わせて使用​​しているようなので、innodb_buffer_pool_size = 2500Mおよびkey_buffer_size = 500Mをお勧めします。 (buffer_poolの設定が高いと、MyISAMのデータキャッシュが不足していました。)
  • Tmpテーブルについては、最も遅いクエリとSHOW CREATE TABLEを見てみましょう。
  • テーブルの断片化を無視します。最適化を気にしないでください。
  • table_open_cacheは数百にする必要があります。 open_files_limitが1Kしかない場合、OSの何かがキャッシュを制限しています。

Aggr_idを一意にすることができる場合は、おそらくそれを主キーにして、idを削除する必要があります。パーティション化のため、一意性制約を設定できないことに注意してください。

ここでは2つのことが絡み合っていることに注意してください。InnoDBに切り替えて、aggr_idをPKにすることです。両方行う場合は、

PRIMARY KEY (aggr_id, craft_id, task_year)

セカンダリキーはありません。根拠:

  • InnoDBには本当にPKが必要です。
  • task_year(パーティションキー)は、一意の(PKを含む)キーごとに存在する必要があります
  • 通常、パーティションキーを最後に置くのが最善です。
  • 他の理由でcraft_idが必要なようですか?特にPKがInnoDB内のデータと共存している場合は特に、削除する必要があります。 (craft_idを必要とするSELECTを示してください。これについては、さらに議論できます。)

InnoDBへの切り替えは、ほとんどの場合「良好」です。落とし穴については私のブログを参照してください: http://mysql.rjweb.org/doc.php/myisam2innodb そこにいる間、ここでパーティションの問題についてお読みください: http:// mysql .rjweb.org/doc.php/partitionmaint パーティショニングがうまくいっていないと結論するかもしれません。

All-InnoDBに移動すると、innodb_buffer_pool_size = 5Gおよびkey_buffer_size = 20Mになります。

1
Rick James