2012-12-03 19 views
10

Mam wiele kłopotów z pamięcią podręczną zapytań na temat projektu: Używam Percona smaku MySQL, te same wersje na moim lokalnym komputerze programistycznym, jak na serwerze produkcyjnym. Teraz włączenie buforowania zapytań daje mi doskonałe wyniki na moim komputerze lokalnym: prawie wszystkie zapytania, które powinny być buforowane, są efektywne.Zapytanie jest buforowane w lokalnej konfiguracji, ale nigdy na serwerze?

Teraz dokładnie te same zapytania nie są buforowane na serwerze produkcyjnym. Wszystko jest dokładnie takie samo; zmienne mysql, zawartość bazy danych, kod code, zalogowany użytkownik, ale przy produkcji tylko garstka zapytań jest buforowana, a najważniejsze są pomijane. I nie mogę zrozumieć, dlaczego :-)

Poszukując rozwiązania, pracuję z następującym zapytaniem, używanym do wybierania 3 najnowszych tematów z tabeli tematów: (jest to najbardziej "ciężki" ! zapytania i jeden na pewno chcesz być buforowane)

SELECT `topic`.* FROM `topics` AS `topic` 
LEFT OUTER JOIN `topics` AS `topic_helper` 
ON (`topic`.`id` = `topic_helper`.`id` 
     AND `topic_helper`.`created_on` < `topic`.`created_on`) 
GROUP BY `topic`.`id` HAVING COUNT(*) < 3 
ORDER BY `topic`.`created_on` DESC; 

tak więc, aby początek, SHOW VARIABLES LIKE '%query_cache% mi dać takie same wyniki, zarówno lokalnych, jak na produkcję:

+------------------------------+----------+ 
| Variable_name    | Value | 
+------------------------------+----------+ 
| have_query_cache    | YES  | 
| query_cache_limit   | 1048576 | 
| query_cache_min_res_unit  | 4096  | 
| query_cache_size    | 10485760 | 
| query_cache_strip_comments | OFF  | 
| query_cache_type    | ON  | 
| query_cache_wlock_invalidate | OFF  | 
+------------------------------+----------+ 

uruchomić powyższy zapytanie zostaje zbuforowany lokalnie po pierwszym uruchomieniu, ponieważ SHOW PROFILE wyraźnie mówi mi Ucha koniec śledzenia:

| Waiting for query cache lock | 0.000001 | 
| Waiting on query cache mutex | 0.000001 | 
| freeing items     | 0.000000 | 
| storing result in query cache | 0.000002 | 
| logging slow query    | 0.000001 | 
| cleaning up     | 0.000006 | 
+--------------------------------+----------+ 

Drugie połączenie zwraca zapytanie z pamięci podręcznej, zgodnie z oczekiwaniami.

Na serwerze produkcyjnym uruchomienie tej kwerendy nigdy nie będzie przechowywane w pamięci podręcznej. Zestaw wyników jest dokładnie taki sam i nie ma wyraźnie żadnych instrukcji, które mogłyby unieważnić buforowanie zapytań (zgodnie z instrukcją pod numerem http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html - Jestem pewien, że powyższe zapytanie jest zgodne z wymaganiami, aby było buforowane.)

przez wzgląd na kompletność, pełnym wyjściu SHOW PROFILE dla tego samego zapytania na serwerze produkcyjnym, jest wklejany tutaj: http://pastebin.com/7Jm5rmVd

Ponadto, warto zauważyć, że chociaż konfiguracja jest taka sama na obu serwerach, mój lokalny Wersja to 5.5.27, nieco nowsza od wersji 5.5.17-55. Czy to możliwe, że to jest problem ...?

Porównałem pełną SHOW VARIABLES; wyjście z obu moim lokalnym serwerze co serwer produkcyjny, aby zobaczyć, czy coś brakowało, ale nic nie różni wyjątkiem strefy czasowej systemu i ścieżki do plików itp zalogować ..

tak, to którakolwiek z was wie, gdzie szukać dalej? A może masz pojęcia, co może być przyczyną tego?

+4

Od twojego linku do podręcznika MySQL, właśnie dowiedziałem się, że "zapytanie również nie jest buforowane [jeśli] użytkownik ma przywilej na poziomie kolumny dla każdej z zaangażowanych tabel". Czy może tak być na twoim serwerze produkcyjnym? Ponadto "wstawianie, aktualizowanie, usuwanie lub inna modyfikacja tabeli powoduje, że wszystkie odpowiednie wpisy w pamięci podręcznej zapytań są przepłukiwane.", Http://dev.mysql.com/doc/refman/5.5/en/query- cache.html). Prawdopodobnie zdarza się to częściej w produkcji niż na serwerze testowym. Możesz chcieć uruchomić swój test w produkcji w czasie niskiego ruchu. – RandomSeed

+0

Cześć YaK, dziękuję za twój wgląd. Tylko do testowania, szybko zmieniłem mojego użytkownika db na root, który nie powinien mieć żadnych przywilejów wstrzymanych. Pamięć podręczna zapytań nadal niestety nie wstawia zapytania. Pracuję również nad serwerem pośredniczącym (który jest oczywiście dokładnym klonem produkcji), więc jestem pewien, że podczas testowania nie ma dużego ruchu :-) Bardzo dziękuję za pomoc! –

+1

Zapytanie nie jest buforowane, jeśli ma wartość niedeterministyczną. Nie wiem, czy liczenie będzie liczone jako niedeterministyczne, spróbuj usunąć licznik i przetestuj, czy zostanie zbuforowany – FabioCosta

Odpowiedz

1

Używamy tutaj serwera Percona i MySQL społeczności.

Pamięć podręczna zapytań jest silna - i niezwykle skomplikowana. Najgorszą rzeczą, jaką MySQL może zrobić, jest zwrócenie starych danych pamięci podręcznej.

MySQL nie tylko buforuje zapytania, ale także dane bazy danych - i wykorzystuje indeksy, aby zwiększyć wydajność.

Wszystko, co może unieważnić pamięć podręczną zapytań, unieważnia ją.

Co do zasady - nie skupiamy się zbytnio na tym, czy jest ona buforowana, czy nie ...ufamy, że MySQL działa w sposób inteligentny - jeśli z jakiegoś powodu uważa, że ​​coś nie powinno być buforowane, nie buforuje go. Jednak robimy to, aby nasze zapytania były tak wydajne i proste, jak to tylko możliwe.

Jeśli mogę tak powiedzieć - myślę, że napotkasz poważne problemy z skalowalnością niezależnie od pamięci podręcznej zapytań, jeśli przykładowe zapytanie jest "jednym z najczęściej używanych". Będzie działał jak pies bez nóg, gdy ten serwer będzie zajęty!

Zgodnie z wpisem do pastebin - tworzona jest co najmniej jedna tabela tymczasowa, prawdopodobnie z powodu zewnętrznego sprzężenia (lub grupowych obiektów BY).

Jestem za normalizacją - ale czasami wydajność wymaga alternatywnej trasy.

Nie możesz cachować niektórych z tych danych samodzielnie, w formie tabeli podsumowań/podsumowań? Sprężarki mogą być tu twoim przyjacielem :)

+0

W trakcie usuwania tego problemu straciłem możliwość śledzenia tego tematu, nie otrzymałem powiadomień. Przepraszam za to. Ostatecznie rozwiązaliśmy go, refaktoryzując naszą logikę aplikacji i upraszczając zapytania. Jak powiedziałeś, zapytanie to było problemem, który czekał, aby się wydarzyć - i nie potrzebowaliśmy go w końcu. Utrzymywanie rzeczy w porządku było tutaj kluczowe. –

Powiązane problemy