Das Einfügen in die folgende Tabelle dauert bis zu 70 Sekunden:
CREATE TABLE IF NOT EXISTS `productsCategories` (
`categoriesId` int(11) NOT NULL,
`productsId` int(11) NOT NULL,
PRIMARY KEY (`categoriesId`,`productsId`),
KEY `categoriesId` (`categoriesId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Die Tabelle enthält ungefähr 100.000 Zeilen und benötigt 7 MB auf der Festplatte.
Gibt es einige Einstellungen in MySQL, die die Schreibleistung verbessern können?
Meine my.cnf
Datei lautet wie folgt:
log-slow-queries="/var/log/mysql/slow-query.log"
long_query_time=1
log-queries-not-using-indexes
innodb_buffer_pool_size=4G
innodb_log_buffer_size=4M
innodb_flush_log_at_trx_commit=2
innodb_thread_concurrency=8
innodb_flush_method=O_DIRECT
query_cache_size = 6G
key_buffer_size = 284M
query_cache_limit = 1024M
thread_cache_size = 128
table_cache = 12800
sort_buffer_size=2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
read_buffer_size=128K
open_files_limit = 1000
table_definition_cache = 1024
table_open_cache = 6000
max_heap_table_size=512M
tmp_table_size=4096M
max_connections=1000
thread_concurrency = 24
Hier ist das Hardware-Setup:
- Dell R710
- RAID10
- 48G RAM
Angesichts dieser Hardware würde ich nicht erwarten, dass das Problem ein Hardware-Engpass ist.
Antworten:
BEOBACHTUNG # 1
Das allererste, was mir auffällt, ist die Tischstruktur
Bitte beachten Sie, dass der
categoriesId
Index und der PRIMARY KEY mit derselben Spalte beginnen. Es ist ein redundanter Index. Da es sich bei dieser Tabelle um InnoDB handelt, ist dercategoriesId
Index aus einem anderen Grund redundant: Alle Sekundärindizes enthalten Schlüssel für gen_clust_index (auch bekannt als Clustered Index; siehe, wofür wird gen_clust_index in MySQL verwendet? ).Wenn Sie den
categoriesId
Index mit entfernenDies wird INSERTs dramatisch verbessern, da keine zusätzliche Wartung des Sekundär- und Clustered-Index durchgeführt werden muss.
BEOBACHTUNG # 2
Wenn Sie Masseneinfügevorgänge ausführen, benötigen Sie einen großen Masseneinfügepuffer .
Bitte beachten Sie meine bisherigen Beiträge dazu:
BEOBACHTUNG # 3
Ihre Protokolldatei ist viel zu klein !!! Es sollte 25% des InnoDB-Pufferpools sein, in Ihrem Fall sollte es 1G sein. In meinem Beitrag erfahren Sie, wie Sie die Größe von InnoDB-Protokolldateien ändern können .
BEOBACHTUNG # 4
Bitte nicht innodb_thread_concurrency setzen !!! Ich habe bei Percona Live NYC aus erster Hand gelernt, diese Einstellung in Ruhe zu lassen . Es ist in MySQL 5.5, MySQL 5.1 InnoDB Plugin und Percona Server 5.1+ standardmäßig deaktiviert.
BEOBACHTUNG # 5
Sie müssen innodb_file_per_table verwenden. Wenn dies deaktiviert ist, mache ich die Dateiverwaltung auf ibdata1 zu einem Albtraum. Bitte lesen Sie meinen Beitrag darüber, wie Sie InnoDB bereinigen können, um dies zu implementieren .
BEOBACHTUNG # 6
Wenn Sie MySQL 5.5 oder Percona Server verwenden, müssen Sie bestimmte Optionen festlegen, damit InnoDB mehrere CPUs / mehrere Kerne verwendet. Bitte lesen Sie meinen Beitrag zu diesen Einstellungen .
BEOBACHTUNG # 7
Du hast
innodb_log_buffer_size=4M
. Der Standardwert ist 8M. Dadurch werden die Redo-Protokolle doppelt so häufig gespült. Das wirkt auch Ihrerinnodb_flush_log_at_trx_commit=2
Einstellung entgegen . Bitte stellen Sie es auf 32M ein. Weitere Informationen finden Sie in der MySQL-Dokumentation zu innodb_log_buffer_size .In Anbetracht dieser Beobachtungen fügen Sie bitte die folgenden Einstellungen hinzu oder ersetzen Sie sie:
quelle
query_cache_size
ist auch enorm. Für jede Einfügung müssen bis zu 6 GB Cache geleert werden.Sie sollten überprüfen
innodb_log_file_size
, ob die Standardeinstellung 5 MB ist, was für schreibintensive Setups recht niedrig ist. Stellen Sie es auf 100M ein. Sie müssen die altenib_logfile*
Dateien löschen , um die Datenbank mit neuen Einstellungen zu starten. Bitte löschen Sie die Protokolldateien nicht, während der DB-Server ausgeführt wird. Sie müssen ihn zuerst stoppen. Wahrscheinlich sollten Sie zuerst die alten Protokolldateien sichern und nicht nur löschen.quelle