web-dev-qa-db-ja.com

InnoDB:INSERT / UPDATEのパフォーマンスが非常に悪い

最近、INSERTとUPDATEに本当に大きな問題があります。私のウェブサイトではすべてのクエリの80%がSELECTですが、クエリが遅いログではINSERTとUPDATEしかありません。私の専用サーバーには32GB RAM、Core i7がありますがSSDドライブはありません。

mysqltunerさんのコメント:

-------- General Statistics --------------------------------------------------
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.6.14
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +Archive -BDB -Federated +InnoDB -ISAM -NDBCluster
Warning: Using a password on the command line interface can be insecure.
Warning: Using a password on the command line interface can be insecure.
[--] Data in MyISAM tables: 203M (Tables: 23)
[--] Data in InnoDB tables: 1G (Tables: 96)
[--] Data in MEMORY tables: 5M (Tables: 4)
[!!] Total fragmented tables: 37

-------- Security Recommendations  -------------------------------------------
Warning: Using a password on the command line interface can be insecure.
[OK] All database users have passwords assigned
Warning: Using a password on the command line interface can be insecure.

-------- Performance Metrics -------------------------------------------------
[--] Up for: 10h 54m 18s (3M q [93.602 qps], 131K conn, TX: 22B, RX: 713M)
[--] Reads / Writes: 83% / 17%
[--] Total buffers: 4.0G global + 1.1M per thread (151 max threads)
[OK] Maximum possible memory usage: 4.2G (12% of installed RAM)
[OK] Slow queries: 0% (535/3M)
[OK] Highest usage of available connections: 4% (7/151)
[OK] Key buffer size / total MyISAM indexes: 8.0M/98.7M
[OK] Key buffer hit rate: 99.7% (10M cached / 28K reads)
[OK] Query cache efficiency: 66.2% (1M cached / 2M selects)
[!!] Query cache prunes per day: 290517
[!!] Sorts requiring temporary tables: 16% (43K temp sorts / 261K sorts)
[OK] Temporary tables created on disk: 17% (20K on disk / 119K total)
[OK] Thread cache hit rate: 99% (7 created / 131K connections)
[OK] Table cache hit rate: 26% (413 open / 1K opened)
[OK] Open file limit used: 0% (125/100K)
[OK] Table locks acquired immediately: 99% (2M immediate / 2M locks)
[OK] InnoDB data size / buffer pool: 1.3G/3.0G

-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    MySQL started within last 24 hours - recommendations may be inaccurate
Variables to adjust:
    query_cache_size (> 32M)
    sort_buffer_size (> 256K)
    read_rnd_buffer_size (> 256K)

私はすでにMySQL設定を最適化しようとしましたが、それはあまり役に立ちませんでした。 my.cnf:

[mysqld]
innodb_buffer_pool_size = 3GB
innodb_flush_method = O_DIRECT

innodb_additional_mem_pool_size=16M
innodb_autoextend_increment = 128M
innodb_log_file_size = 500M
innodb_log_buffer_size = 750M

query_cache_type = 1
query_cache_limit = 32M
query_cache_size  = 32M

tmp_table_size = 220M
max_heap_table_size = 220M

sql_mode=
event-scheduler=1
long_query_time=2

私の遅いクエリログのクエリのほとんどは本当に簡単です。テーブルは中程度なので、有線です。ただし、最も問題のあるクエリは、〜900kレコード(InnoDB)を持つテーブルへのINSERTです。

CREATE TABLE `topic_marking` (
    `topic_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
    `user_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
    `forum_id` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0',
    `mark_time` INT(10) UNSIGNED NOT NULL,
    UNIQUE INDEX `topic_id_2` (`topic_id`, `user_id`),
    INDEX `forum_id` (`forum_id`),
    INDEX `topic_id` (`topic_id`),
    INDEX `user_id` (`user_id`),
    CONSTRAINT `topic_marking_ibfk_1` FOREIGN KEY (`topic_id`) REFERENCES `topic` (`topic_id`) ON DELETE CASCADE,
    CONSTRAINT `topic_marking_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`) ON DELETE CASCADE,
    CONSTRAINT `topic_marking_ibfk_3` FOREIGN KEY (`forum_id`) REFERENCES `forum` (`forum_id`) ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
ROW_FORMAT=COMPACT;

あなたが見ることができるように、たくさんのインデックスとforeginキーがあります。私はそれが問題になるのではないかと思ったので、すべての外部キーを削除し、2つのインデックス(topic_id_2とforum_id)のみを残すことにしました。まあ、それは少しは役に立ちましたが、問題を排除しませんでした。

追加のSDDドライブを購入する以外に、パフォーマンスを向上させるために他に何ができますか?

最大50クエリ/秒です。単純なUPDATEクエリをプロファイリングすると、次のような結果が得られます。

starting
0.000028
checking permissions
0.000004
Opening tables
0.000017
init
0.000014
System lock
0.000026
updating
0.000033
end
0.000003
Waiting for query cache lock
0.000002
end
0.000066
query end
7.456112
closing tables
0.000019
freeing items
0.000013
logging slow query
0.000054
cleaning up
0.000011

そう query_endは7秒ほどかかります!どういう意味ですか?

1
Bald

これはおそらくtxフラッシングです。

https://stackoverflow.com/questions/6937443/query-end-step-very-long-at-random-times に似たものがないかチェックしてください.

そこに、追加

innodb_flush_log_at_trx_commit = 0

助けた。

典型的な7200RPMの大きいが遅いディスクを実行する場合、IOPS予算は非常に制限されます。ここでの唯一の実際の手順は、嘘をついている(アップしていない-コミットしていない、またはディスクを物理的に書き戻しモードにして、書き込みが発生する前に確認している)、またはIOPSを増やす(SSDが本当に優れている場所です)ことで、簡単にSSDを取得できます60.000 IOPS-予算の400倍です。

電源障害をカバーするためのバッテリーを準備していない限り、横になることはお勧めできません。おそらく、バッテリーが上部にあるRAIDコントローラでも同様です。それが投資である場合、SSDは物事を行うための絶対的に最も費用効果の高い方法です。

IOバジェット。

1
TomTom