Interogare lentă pentru tabela wp_options

6 nov. 2012, 11:07:55
Vizualizări: 39.3K
Voturi: 21

Am monitorizat jurnalul interogărilor lente ale site-ului bazat pe WP (cu valoarea implicită a long_query_time setată la 10) și am observat că următoarea interogare este frecvent înregistrată -

# User@Host: root[root] @ localhost []
# Query_time: 0  Lock_time: 0  Rows_sent: 394  Rows_examined: 458
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';

Nu înțeleg cum o tabelă atât de mică poate să dureze atât de mult timp pentru a executa interogarea. Este aceasta doar un simptom al unei alte probleme? (În prezent rulează Moodle, phpbb și WP pe o mașină virtuală dedicată).

1
Comentarii

Vot pentru închiderea acestei întrebări deoarece a fost pusă acum 8 ani. În actualizările recente ale WordPress, această problemă a fost rezolvată.

Prasad Ajinkya Prasad Ajinkya
18 nov. 2020 14:15:31
Toate răspunsurile la întrebare 4
9
18

Actualizare: Motivul pentru care interogarea este înregistrată este că nu utilizează un index. Timpul de execuție al interogării este 0, adică de fapt se execută rapid. Puteți dezactiva opțiunea "log-queries-not-using-indexes" dacă nu doriți ca acestea să fie înregistrate.

Tabela wp_options nu are index pe coloana autoload (acum ar trebui să aibă, a fost adăugată în schema de bază a WordPress pe 15 august 2019), așa că interogarea face un scan complet al tabelei. În general, această tabelă nu ar trebui să devină prea mare, deci nu ar fi o problemă, dar presupun că în cazul dumneavoastră s-a întâmplat cumva asta.

Adăugarea unui index ar putea rezolva problema, dar după cum a menționat TheDeadMedic în comentarii, s-ar putea să nu funcționeze dacă valorile din autoload sunt fie majoritar 'yes', fie distribuite uniform între 'yes' și 'no':

Mai întâi, executați această interogare pentru a vedea cum arată distribuția:

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

Dacă majoritatea covârșitoare sunt setate pe 'no', puteți rezolva problema pe moment prin adăugarea unui index pe coloana autoload.

ALTER TABLE wp_options ADD INDEX (`autoload`);

Cu toate acestea, ar fi bine să aflați de ce această tabelă a devenit prea mare. Posibil un plugin prost scris care face ceva suspect.

6 nov. 2012 16:39:56
Comentarii

Mă îndoiesc că un index în acest caz ar aduce vreun beneficiu - verifică acest articol despre cardinalitate.

TheDeadMedic TheDeadMedic
6 nov. 2012 16:50:39

Depinde dacă majoritatea opțiunilor sunt setate să se încarce automat sau nu. Aș crede că nu, dar oricum tabela nu ar trebui să devină atât de mare, deci ceva miroase a probleme.

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

Am actualizat răspunsul meu pentru a adăuga câteva detalii despre verificarea distribuției valorilor.

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

Indexul nu va reduce în mod specific timpul de execuție, dar va preveni scanarea completă a tabelului și blocurile asociate.

Steve Steve
6 nov. 2012 17:45:28

Tocmai am observat comentariul și mi-am dat seama că răspunsul meu este complet greșit. Interogarea nu este de fapt lentă... este doar înregistrată în jurnalul de interogări lente pentru că nu folosește un index.

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

458 de rânduri în wp_options nu este deloc un număr deosebit de mare.

Steve Steve
6 nov. 2012 19:10:14

Mulțumesc pentru această întrebare și răspuns, am descoperit că aveam 90k de intrări în tabelul wp_options, dintre care 88.5k erau setate la autoload false. Restul erau toate intrări "transient" adăugate de pluginuri (presupun pentru caching?). Adăugarea unui index pe coloana autoload a scăzut instantaneu încărcarea mySql de la o medie de 89% la 2.5%. Agenții de monitorizare arată că timpul de răspuns al site-ului meu a scăzut de la 1900ms la 500ms. Aceasta a fost o schimbare radicală pentru mine.

Mordred Mordred
25 mar. 2017 05:41:25

Pluginul woocommerce adaugă transient_external_ip_address și transient_timeout_external_ip_address în wp_options deoarece stochează IP-ul vizitatorilor pentru scopuri de geolocalizare (nu știu de ce). Cel mai rău este că pluginul nu va șterge intrările după expirarea timeout-ului, așa că ajungi cu mii de date inutile...

fat_mike fat_mike
24 iul. 2017 07:32:56

Acesta este un post vechi, 7 ani mai târziu au adăugat în sfârșit niște indexări pe tabelul wp_options pe 15 august 2019. Vezi: https://github.com/WordPress/WordPress/commit/716958625410ff83a3ae4ff46bb74b2eebcf41a5#diff-c7abc93dc5e86d04912fe01fc19c5e12

Mike Kormendy Mike Kormendy
2 mai 2020 18:31:06
Arată celelalte 4 comentarii
0

Am dat peste interogarea menționată în mytop care rulează pe serverul meu acum câteva zile - și de fapt a durat destul de mult (aproximativ 10 secunde) pentru fiecare interogare! Deci există situații reale în care wp_options poate crește la dimensiuni problematice. În cazul meu, bănuiesc că plugin-ul de caching Cachify este responsabil pentru umflarea wp_options.

Datele acestui wp_options în particular:

5.309 rânduri
130MB de date

Ca soluție, am adăugat indexul similar cu soluția postată de Vinay Pai, care a rezolvat problema fără probleme.

27 mar. 2013 20:19:42
1

Tabelul meu wp_options avea doar aproximativ 235 de rânduri de date. Am încercat să indexez tabelul, dar nu a ajutat.

Se pare că aproximativ 150 de opțiuni temporare (transiente) au fost inserate în tabel, dar nu au fost șterse automat.

Nu știu dacă este legat sau nu, dar am verificat fișierele /var/log/apache2/access.log și am observat că mai multe servere Amazon Web Services (presupuse compromise) (adrese IP începând cu 54.X.X.X și 32.X.X.X) au încercat să exploateze /~web-root-dir/xmlrpc.php.

După o depanare, am interogat tabelul wp_options pentru nume de opțiuni care conțineau "transient"

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

Unul dintre câmpurile returnate de această interogare este 'option_value', care are un tip de date LONGTEXT. Conform documentației MySQL, un câmp LONGTEXT (pentru fiecare rând) poate stoca până la 4 Gigabytes de date.

Când am executat interogarea, unele dintre rânduri (cele care conțineau "transient") aveau cantități uriașe de date în câmpul option_value. Analizând rezultatele, am observat și încercări de a injecta comenzi în procesul wp-cron, în speranța că acestea vor fi executate în timpul ciclului/ciclurilor cron.

Soluția mea a fost să șterg toate rândurile "transient". Acest lucru nu va afecta serverul, deoarece rândurile "transient" se vor repopula automat (dacă trebuie să fie acolo).

După aceasta, serverul a devenit din nou responsiv.

Interogare pentru a șterge aceste rânduri:

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

Am adăugat și blocurile superioare de adrese IP AWS /8 în firewall-ul meu (-:

7 sept. 2017 04:55:15
Comentarii

Da. Și eu mă confruntam cu un "timp de încărcare de 40 de secunde" până când am descoperit că aveam 20.000 de înregistrări wp_option cu date masive care se încărcau la fiecare pagină. Eliminarea lor a accelerat considerabil site-ul.

JasonGenX JasonGenX
12 feb. 2019 19:34:29
0

Actualizare legată de Index pentru câmpul autoload în tabelul wp_options:

Un index a fost adăugat la wp_options.autoload în WordPress 5.3. Vezi Jurnalul modificărilor WordPress 5.3

De asemenea, poți observa că Index este disponibil și pentru alte coloane din tabelul wp_options:

SHOW INDEX from wp_options
19 aug. 2020 10:47:36