Powolne zapytanie dla tabeli wp_options

16

Śledzę dziennik wolnych zapytań witryny opartej na WP (z domyślną wartością long_query_time ustawioną na 10) i zauważyłem, że następujące zapytanie jest często rejestrowane -

# 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';

Nie rozumiem, jak wykonanie tak małego stołu może zająć tyle czasu. Czy to tylko objaw jakiegoś innego problemu? (Obecnie uruchomione Moodle, phpbb i WP na dedykowanej maszynie wirtualnej).

Prasad Ajinkya
źródło

Odpowiedzi:

16

Aktualizacja : Powodem rejestrowania zapytania jest to, że nie używa indeksu . Czas zapytania wynosi 0, tzn. Faktycznie wykonuje się szybko. Możesz wyłączyć opcję „log-queries-not-using-indexes”, jeśli nie chcesz, aby były rejestrowane.

Tabela wp_options nie ma indeksu przy autoloadie, więc zapytanie kończy się pełnym skanowaniem tabeli. Ogólnie rzecz biorąc, stół nie powinien być zbyt duży, więc nie jest to problem, ale domyślam się, że tak się stało w twoim przypadku.

Dodanie indeksu może rozwiązać problem, ale jak zauważył TheDeadMedic w komentarzach, może się nie zdarzyć, jeśli wartości autoload będą w większości tak lub równomiernie rozdzielone między tak i nie:

Najpierw wykonaj to zapytanie, aby zobaczyć, jak wygląda dystrybucja:

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

jeśli większość z nich jest ustawiona na „nie”, możesz na razie rozwiązać problem, dodając indeks przy autoloadie.

ALTER TABLE wp_options ADD INDEX (`autoload`);

Możesz jednak chcieć dowiedzieć się, dlaczego ten stół stał się zbyt duży. Prawdopodobnie źle napisana wtyczka robi coś podejrzanego.

Vinay Pai
źródło
2
Wątpię, czy indeks w tym przypadku przyniósłby jakiekolwiek korzyści - sprawdź ten artykuł na temat liczności .
TheDeadMedic
Zależy, czy większość opcji jest ustawiona na automatyczne ładowanie, czy nie. Nie sądzę, ale w tabeli i tak nigdy nie powinno być tak duże, więc dzieje się coś podejrzanego.
Vinay Pai,
1
Zaktualizowałem przez odpowiedź, aby dodać trochę o sprawdzaniu rozkładu wartości.
Vinay Pai,
1
Właśnie zauważyłem komentarz i zdałem sobie sprawę, że moja odpowiedź jest całkowicie błędna. Zapytanie nie jest właściwie wolne ... jest po prostu logowane w dzienniku powolnych zapytań, ponieważ nie używa indeksu.
Vinay Pai,
1
Dzięki temu pytaniu i odpowiedzi odkryłem, że mam 90 000 wpisów w mojej tabeli wp_options, z których 88,5 000 zostało ustawione na automatyczne ładowanie false. Reszta to wszystkie „przejściowe” wpisy dodane przez wtyczki (przypuszczalnie do buforowania?). Dodanie indeksu do kolumny automatycznego ładowania obniżyło moje obciążenie mySql ze średnio 89% do 2,5% natychmiast. Agenci monitorujący pokazują, że czas reakcji mojej witryny spadł z 1900 ms do 500 ms. To był dla mnie gamechanger.
Mordred,
5

Natknąłem się na zapytanie wspomniane w mytopie uruchomionym na moim serwerze kilka dni temu - i rzeczywiście zajęło to sporo czasu (około 10 sekund) dla każdego zapytania! Są więc sytuacje w świecie rzeczywistym, w których wp_options może wzrosnąć do problematycznych rozmiarów. W moim przypadku podejrzewam, że wtyczka buforująca Cachify jest odpowiedzialna za wzdęcie wp_options.

Dane tego konkretnego wp_options:

5,309 rows
130MB of data

Jako rozwiązanie dodałem indeks podobny do rozwiązania opublikowanego przez Vinay Pai, który rozwiązał problem bezbłędnie.

Jan Papenbrock
źródło
1

Moja tabela wp_options zawierała tylko około 235 wierszy danych. Próbowałem indeksować tabelę, ale to nie pomogło.

Okazuje się, że około 150 opcji przejściowych zostało wstawionych do tabeli, ale nie zostało automatycznie usuniętych.

Nie wiem, czy jest to powiązane, czy nie, ale przeglądałem moje pliki /var/log/apache2/access.log i zauważyłem, że wiele (prawdopodobnie zagrożonych) serwerów Amazon Web Services (adresy IP zaczynające się od 54). XXX i 32.XXX) próbowały wykorzystać katalog /~web-root-dir/xmlrpc.php.

Po rozwiązywaniu problemów zapytałem tabelę wp_options o nazwy opcji zawierające „przejściowe”

wybierz * z wp_options gdzie nazwa_opcji jak „% transient %”;

Jednym z pól zwróconych z tego zapytania jest „wartość_opcji”, która ma typ danych LONGTEXT. Zgodnie z dokumentacją mySQL, pole LONGTEXT (dla każdego wiersza) może pomieścić do 4 gigabajtów danych.

Kiedy wykonałem zapytanie, niektóre wiersze (pamiętaj, że pracowały z wierszami zawierającymi „przejściowy”) zawierały ogromne ilości danych w polu option_value. Przeglądając wyniki, zobaczyłem również coś, co wyglądało jak próby wstrzyknięcia poleceń do procesu wp-cron z nadzieją, że zostaną one wykonane w cyklu (cyklach) crona.

Moim rozwiązaniem było usunięcie wszystkich „przejściowych” wierszy. Nie zaszkodzi to serwerowi, ponieważ wiersze „przejściowe” zostaną automatycznie ponownie wypełnione (jeśli powinny tam być).

Po wykonaniu tej czynności serwer ponownie zareagował.

Zapytanie o usunięcie tych wierszy:

USUŃ z wp_options gdzie nazwa_opcji jak „% transient %”;

Dodałem również adres IP AWS / 8 superbloków do mojej zapory ogniowej (-:

Ex_Military
źródło
Tak. Miałem też „40 sekund ładowania”, dopóki nie odkryłem, że mam 20 000 rekordów wp_option z ogromnymi danymi wczytywanymi z każdą stroną. Usunięcie tych znacznie przyspieszyło witrynę.
JasonGenX