Czy zapytania MySQL w pamięci podręcznej?

19

Łączę bazę danych MySQL z PHP Data Objects (PDO) i wykonuję rozległe zapytanie SQL. Zwykle zajmuje to około 1500 ms; Nadal muszę to zoptymalizować. Kiedy uruchamiam skrypt PHP dwa razy z krótką przerwą pomiędzy nimi, zapytanie zajmuje tylko około 90 ms. Kwerenda jest w obu przypadkach taka sama. Po uruchomieniu skryptu z tym samym zapytaniem po pewnym czasie ponownie zajmuje 1500 ms.

Dlaczego? Czy baza danych buforuje się automatycznie? Czy baza danych zapisuje pamięć podręczną i automatycznie ją usuwa?

Zakładam, że PHP nie może buforować wyników, ponieważ dzieje się tak w dwóch różnych wątkach. Nie sądzę, że PHP zbuforuje wyniki, ponieważ nie może wiedzieć, czy baza danych uległa zmianie.

Mam skrypt uruchamiający się co minutę, aby wstawić nowe wiersze do bazy danych. Może to być również przyczyną, że po pewnym czasie zajmuje to 1500 ms; pamięć podręczna zostałaby usunięta, ponieważ odpowiednie tabele nie są już takie same.

Peter Mortensen
źródło
Pokaż mi swój kod. Nie potrzebuję twojego zapytania, tylko sposób, w jaki go testujesz.
3
Tak, mySQL buforuje zapytania. To takie sprytne.
@Kasyx jaki kod? To tylko podstawowy PDO, ale nie sądzę, że PHP może go buforować, ponieważ uruchamiam skrypt PHP dwa razy, nie uruchamiam zapytania dwa razy w jednym skrypcie. Czy mógłbyś również wyjaśnić, dlaczego edytowałeś pdo, podczas gdy nie ma to tak naprawdę znaczenia dla pytania?
3
Wszystkie DBMS mają pewnego rodzaju pamięć podręczną na poziomie strony. Wiele z nich wychodzi poza buforowanie planów wykonania zapytań, a nawet wyników zapytań (w tym MySQL ). Podejrzewam, że ta ostatnia rzecz jest głównym winowajcą twojego zaobserwowanego zachowania.
Branko Dimitrijevic
Robisz wkładki co minutę? Sortuj że w pierwszej kolejności!
Grant Thomas

Odpowiedzi:

15

Jest to prawdopodobnie artefakt pamięci podręcznej zapytań MySQL .

Wykonujesz zapytanie SQL, MySQL buforuje jego wynik, a następne wykonanie jest szybkie. Po uruchomieniu skryptu w celu wstawienia danych do tabel, do których odwołuje się zapytanie, pamięć podręczna wyników zostaje unieważniona i zapytanie musi zostać wykonane „na prawdę” następnym razem.

Z dokumentacji MySQL połączonej powyżej:

Mieszanka zapytań składająca się prawie całkowicie ze stałego zestawu instrukcji SELECT ma większe szanse na skorzystanie z włączenia pamięci podręcznej niż mieszanka, w której częste instrukcje INSERT powodują ciągłe unieważnianie wyników w pamięci podręcznej.

Branko Dimitrijevic
źródło
5

Tak, mySQL (podobnie jak wszystkie inne popularne produkty baz danych) buforuje zapytania, które są do niego kierowane.

Buforowanie jest dość sprytne - często może użyć pamięci podręcznej dla zapytania, nawet jeśli dokładne parametry zapytania nie są takie same. Może to mieć duży wpływ na wydajność.

Buforowanie jest kontrolowane całkowicie w oprogramowaniu serwera DB; nie masz wglądu w zawartość bufora ani jak długo dany element pozostaje w buforze; może być nadpisany w dowolnym momencie, w zależności od tego, jakie inne zapytania są wywoływane itp. Ma on na celu zwiększenie wydajności, ale nie należy polegać na wydajności.

Możesz przeczytać więcej na ten temat tutaj w podręczniku MySQL .

Ponadto użycie PDO pozwala pisać zapytania jako „Przygotowane instrukcje”, wiążąc parametry, a nie kodując je na stałe w postaci ciągów tekstowych. Ma to również wpływ na buforowanie na serwerze DB, a w przypadku powtarzających się zapytań poprawi również wydajność.


źródło
2
„Począwszy od MySQL 5.1.17, pamięć podręczna zapytań jest używana dla przygotowanych instrukcji zgodnie z warunkami opisanymi w Rozdziale 8.6.3.1,„ Jak działa pamięć podręczna zapytań ”. Przed 5.1.17 pamięć podręczna zapytań nie była używana dla przygotowanych instrukcji.” dev.mysql.com/doc/refman/5.1/en/query-cache.html
1
wspólne dla wszystkich innych popularnych produktów bazodanowych ”: jest to nieco mylące. Prawie żaden DBMS nie buforuje wyników zapytań tak, jak robi to MySQL. DBMS zwykle tylko stół cache (lub indeks) dane , a nie zapytań wyniki . Większość z nich buforuje plan wykonania kwerendy (i kwerendę „źródło”)
a_horse_w_na_nazwie
3
„często może używać pamięci podręcznej dla zapytania, nawet jeśli dokładne parametry zapytania nie są takie same” jest całkowicie niepoprawny. Zapytanie musi być bajt po bajcie identyczne z poprzednio wykonanym i wciąż buforowanym zapytaniem, aby mogło być obsługiwane z pamięci podręcznej. Nawet różnica między SELECT *i select *oznacza, że ​​poza tym identyczne zapytanie nie będzie obsługiwane z pamięci podręcznej. dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html . Wysłano link 5.1 w celu zachowania spójności, ale dotyczy wszystkich wersji.
Michael - sqlbot