Query lenta per la tabella wp_options

6 nov 2012, 11:07:55
Visualizzazioni: 39.3K
Voti: 21

Ho monitorato il log delle query lente del sito basato su WP (con il valore predefinito di long_query_time impostato a 10) e ho notato che la seguente query viene spesso registrata -

# Utente@Host: root[root] @ localhost []
# Tempo_Query: 0  Tempo_Lock: 0  Righe_Inviate: 394  Righe_Esaminate: 458
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';

Non capisco come una tabella così piccola possa impiegare così tanto tempo per l'esecuzione. È solo un sintomo di qualche altro problema? (Attualmente sto eseguendo Moodle, phpBB e WP su una VM dedicata).

1
Commenti

Voto per chiudere questa domanda perché è stata posta 8 anni fa. Negli aggiornamenti recenti di WP questo problema è stato risolto.

Prasad Ajinkya Prasad Ajinkya
18 nov 2020 14:15:31
Tutte le risposte alla domanda 4
9
18

Aggiornamento: Il motivo per cui la query viene registrata è che non utilizza un indice. Il tempo di esecuzione della query è 0, cioè in realtà viene eseguita velocemente. Puoi disabilitare l'opzione "log-queries-not-using-indexes" se non vuoi che queste query vengano registrate.

La tabella wp_options non ha un indice su autoload (dovrebbe averlo ora, è stato aggiunto allo schema di core di WP il 15 agosto 2019), quindi la query finisce per fare una scansione completa della tabella. In genere quella tabella non dovrebbe diventare troppo grande, quindi non è un problema, ma immagino che nel tuo caso sia successo in qualche modo.

Aggiungere un indice potrebbe risolvere il problema, ma come ha sottolineato TheDeadMedic nei commenti, potrebbe non farlo se i valori di autoload sono per la maggior parte 'yes' o distribuiti equamente tra 'yes' e 'no':

Per prima cosa, esegui questa query per vedere come è distribuito:

SELECT COUNT(*), autoload FROM wp_options GROUP BY autoload;

Se la grande maggioranza è impostata su 'no', puoi risolvere il problema per ora aggiungendo un indice su autoload.

ALTER TABLE wp_options ADD INDEX (`autoload`);

Tuttavia, potresti voler capire perché quella tabella è diventata troppo grande. Forse qualche plugin scritto male sta facendo qualcosa di strano.

6 nov 2012 16:39:56
Commenti

Dubito che un indice in questo caso offrirebbe alcun vantaggio - dai un'occhiata a questo articolo sulla cardinalità.

TheDeadMedic TheDeadMedic
6 nov 2012 16:50:39

Dipende se la maggior parte delle opzioni sono impostate per il caricamento automatico o meno. Penso di no, ma comunque la tabella non dovrebbe mai diventare così grande, quindi c'è qualcosa di strano in corso.

Vinay Pai Vinay Pai
6 nov 2012 17:05:27

Ho aggiornato la mia risposta aggiungendo qualcosa sul controllo della distribuzione dei valori.

Vinay Pai Vinay Pai
6 nov 2012 17:14:01

L'indice non ridurrà specificamente il tempo di esecuzione, ma impedirà la scansione completa della tabella e i blocchi associati.

Steve Steve
6 nov 2012 17:45:28

Ho appena notato il commento e mi sono reso conto che la mia risposta è completamente sbagliata. La query in realtà non è lenta... viene solo registrata nel log delle query lente perché non utilizza un indice.

Vinay Pai Vinay Pai
6 nov 2012 19:00:16

458 righe in wp_options non sono affatto particolarmente numerose.

Steve Steve
6 nov 2012 19:10:14

Grazie a questa domanda e risposta ho scoperto di avere 90k voci nella mia tabella wp_options, 88.5k delle quali erano impostate su autoload false. Il resto erano tutte voci "transient" aggiunte da plugin (presumibilmente per la cache?). Aggiungere un indice alla colonna autoload ha fatto crollare il carico mySql da una media dell'89% al 2.5% all'istante. Gli agenti di monitoraggio mostrano che il tempo di risposta del mio sito è sceso da 1900ms a 500ms. È stato un punto di svolta per me.

Mordred Mordred
25 mar 2017 05:41:25

Il plugin woocommerce aggiunge transient_external_ip_address e transient_timeout_external_ip_address in wp_options poiché memorizzano l'IP dei visitatori per scopi di geolocalizzazione (non so perché). La cosa peggiore è che il plugin non rimuove le voci dopo il timeout, quindi ti ritrovi con migliaia di dati inutili...

fat_mike fat_mike
24 lug 2017 07:32:56

Questo è un post vecchio, 7 anni dopo hanno finalmente aggiunto un po' di indicizzazione alla tabella wp_options il 15 agosto 2019. Vedi: https://github.com/WordPress/WordPress/commit/716958625410ff83a3ae4ff46bb74b2eebcf41a5#diff-c7abc93dc5e86d04912fe01fc19c5e12

Mike Kormendy Mike Kormendy
2 mag 2020 18:31:06
Mostra i restanti 4 commenti
0

Mi sono imbattuto nella query menzionata in mytop in esecuzione sul mio server qualche giorno fa - e in realtà richiedeva parecchio tempo (circa 10 secondi) per ogni query! Quindi esistono situazioni reali in cui wp_options può crescere fino a dimensioni problematiche. Nel mio caso sospetto che il plugin di caching Cachify sia responsabile dell'ingrandimento di wp_options.

Dati di questo specifico wp_options:

5.309 righe
130MB di dati

Come soluzione, ho aggiunto l'indice in modo simile alla soluzione postata da Vinay Pai, che ha risolto il problema senza intoppi.

27 mar 2013 20:19:42
1

La mia tabella wp_options conteneva solo circa 235 righe di dati. Ho provato a indicizzare la tabella, ma non ha aiutato.

Si è scoperto che circa 150 opzioni transient erano state inserite nella tabella, ma non erano state eliminate automaticamente.

Non so se sia correlato, ma stavo analizzando i miei file /var/log/apache2/access.log e ho notato che diversi server (presumibilmente compromessi) di Amazon Web Services (indirizzi IP che iniziano con 54.X.X.X e 32.X.X.X) stavano tentando di sfruttare /~web-root-dir/xmlrpc.php.

Dopo alcuni tentativi di risoluzione dei problemi, ho interrogato la tabella wp_options per i nomi delle opzioni che contenevano "transient":

select * from wp_options where option_name like '%transient%';

Uno dei campi restituiti da questa query è 'option_value' che ha un tipo di dato LONGTEXT. Secondo la documentazione di MySQL, un campo LONGTEXT (per ogni riga) può contenere fino a 4 gigabyte di dati.

Quando ho eseguito la query, alcune delle righe (ricordiamo che stavamo lavorando con quelle contenenti "transient") avevano quantità enormi di dati nel campo option_value. Esaminando i risultati, ho anche visto quelli che sembravano tentativi di iniettare comandi nel processo wp-cron con la speranza che venissero eseguiti durante i cicli cron.

La mia soluzione è stata eliminare tutte le righe "transient". Questo non danneggia il server perché le righe "transient" verranno ripopolate automaticamente (se dovessero esserci).

Dopo averlo fatto, il server è tornato reattivo.

Query per eliminare queste righe:

DELETE from wp_options where option_name like '%transient%';

Ho anche aggiunto i superblocchi /8 degli indirizzi IP AWS al mio firewall (-:

7 set 2017 04:55:15
Commenti

Sì. Anch'io avevo problemi con "tempi di caricamento di 40 secondi" finché non ho scoperto di avere 20.000 record wp_option con dati enormi che venivano caricati in ogni singola pagina. Rimuoverli ha velocizzato notevolmente il sito.

JasonGenX JasonGenX
12 feb 2019 19:34:29
0

Aggiornamento relativo all'indice per il campo autoload nella tabella wp_options:

È stato aggiunto un indice a wp_options.autoload in WordPress 5.3. Vedi Changelog di WordPress 5.3

Puoi anche vedere che l'indice è disponibile per altre colonne nella tabella wp_options:

SHOW INDEX from wp_options
19 ago 2020 10:47:36