MySQL Slow Writes


8

Il completamento degli inserti nella tabella seguente richiede fino a 70 secondi:

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;

Ci sono circa 100.000 righe nella tabella e ci vogliono 7 MB sul disco.

Ci sono alcune impostazioni in MySQL che possono migliorare le prestazioni di scrittura?

Il mio my.cnffile è il seguente:

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

Ecco la configurazione dell'hardware:

  • Dell R710
  • RAID10
  • 48G RAM

Dato questo hardware, non mi aspetto che il problema sia un collo di bottiglia dell'hardware.


Potete fornire alcuni dati oggettivi? Registri, metodologia e risultati di test / benchmarking, questo genere di cose?
womble

Che tipo di registri ti piacerebbe vedere? L'unica cosa che vedo perché ci vuole così tanto tempo è in de mtop . Proverei cose come cambiare la tabella in una tabella myisam, limiti di memoria più alti, thread più alti.
Ronn0,

L'impostazione migliore per migliorare mysql ... è passare a Postgres Lol
Antony Gibbs,

thread_concurrency = 24 non ha alcun effetto ... puoi scaricare quella riga
Antony Gibbs

Risposte:


16

OSSERVAZIONE # 1

La prima cosa che attira la mia attenzione è la struttura del tavolo

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;

Si noti che l' categoriesIdindice e il PRIMARY KEY iniziano con la stessa colonna. È un indice ridondante. Poiché questa tabella è InnoDB, l' categoriesIdindice è ridondante per un altro motivo: tutti gli indici secondari contengono chiavi in ​​gen_clust_index (alias Clustered Index; vedi a cosa serve gen_clust_index in mysql? )

Se si rimuove l' categoriesIdindice con

ALTER TABLE productsCategories DROP INDEX categoriesId;

ciò migliorerà notevolmente gli INSERTI a causa del fatto che non è necessario eseguire una manutenzione aggiuntiva dell'indice secondario e cluster.

OSSERVAZIONE # 2

Se si stanno eseguendo operazioni di inserimento bulk, è necessario un buffer di inserimento bulk di grandi dimensioni .

Si prega di vedere i miei post precedenti su questo:

OSSERVAZIONE # 3

La dimensione del file di registro è troppo piccola !!! Dovrebbe essere il 25% del pool di buffer InnoDB, che nel tuo caso dovrebbe essere 1G. Vedi il mio post su come ridimensionare i file di registro di InnoDB .

OSSERVAZIONE # 4

Per favore, non impostare innodb_thread_concurrency !!! Ho imparato in prima persona al Percona Live di New York a lasciare da solo quell'ambientazione . È disabilitato per impostazione predefinita in MySQL 5.5, MySQL 5.1 InnoDB Plugin e Percona Server 5.1+.

OSSERVAZIONE # 5

Devi usare innodb_file_per_table. Se questo è disabilitato, faccio della manutenzione dei file su ibdata1 un incubo. Si prega di leggere il mio post su come ripulire InnoDB per implementarlo .

OSSERVAZIONE # 6

Se si utilizza MySQL 5.5 o Percona Server, è necessario impostare alcune opzioni per fare in modo che InnoDB utilizzi più CPU / più core. Si prega di consultare il mio post su tali impostazioni .

OSSERVAZIONE # 7

Hai innodb_log_buffer_size=4M. L'impostazione predefinita è 8M. Ciò causerà il doppio dello svuotamento dei registri di ripristino. Ciò contrasterà anche le tue innodb_flush_log_at_trx_commit=2impostazioni. Si prega di impostarlo su 32M. Inoltre, consulta la documentazione di MySQL su innodb_log_buffer_size .

Alla luce di queste osservazioni, si prega di aggiungere o sostituire le seguenti impostazioni:

[mysqld]
innodb_thread_concurrency = 0
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000
innodb_file_per_table
innodb_log_file_size=1G
innodb_log_buffer_size=1G
bulk_insert_buffer_size = 256M

Wow grazie! Ho stampato tutti i punti e ci ho lavorato ora e lo ho salvato nel cervello per aiutare altre persone in futuro. Grazie molto!
Ronn0,

2
query_cache_sizeè anche enorme. Ogni inserto richiederà fino a 6 GB di cache per essere scaricato.
Aaron Brown,

@AaronBrown Sono d'accordo. Ho letto nel libro MySQL ad alte prestazioni che InnoDB fa cose noiose con l'ID della transazione sulla tabella InnoDB nella cache delle query che rende inutile, per non dire lento, usare una cache delle query. In effetti, MySQL 4.1 ha la cache delle query disabilitata per InnoDB.
RolandoMySQLDBA

Penso che la cache delle query sia completamente separata dal motore di archiviazione. Fondamentalmente serializza tutte le operazioni di scrittura forzando tutto ciò che passa e scansiona la cache delle query per invalidare le query. Non ho mai trovato un caso d'uso per questo e ha sempre causato problemi.
Aaron Brown,

un'altra cosa da aggiungere: query_cache_size = 6G <- questo è totalmente e assolutamente assurdo. La cache delle query è spesso disabilitata meglio e sicuramente non dovrebbe essere più lager di 32M o 64M. Il sovraccarico di mantenere una cache di query 6G sta sicuramente danneggiando le prestazioni.
Gavin Towey,

0

È necessario verificare che innodb_log_file_sizel'impostazione predefinita sia 5M, che è piuttosto bassa per le impostazioni ad alta intensità di scrittura. Valuta di impostarlo su 100M. Dovrai eliminare i vecchi ib_logfile*file per avviare il DB con nuove impostazioni. Non eliminare i file di registro mentre il server DB è in esecuzione, è necessario prima interromperlo. Probabilmente dovresti prima eseguire il backup dei vecchi file di registro, non solo eliminarli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.