2009-10-26 18 views
5

Po pewnym oczekiwanym wzroście naszej usługi, wszystkie nagłe aktualizacje trwają bardzo długo, były one dość szybkie, aż do stołu osiągnęły około 2 MB rekordów, teraz zajmują około 40 60 sekund każdy.Aktualizacja MySQL trwała (zbyt) długo

update table1 set field1=field1+1 where id=2229230; 
Query OK, 0 rows affected (42.31 sec) 
Rows matched: 1 Changed: 0 Warnings: 0 

Oto typy pól:

`id` bigint(20) NOT NULL auto_increment, 
`field1` int(11) default '0', 

Wynik z profilowaniem, do wyłączników kontekście, który jest jedynym, który wydaje się mieć wysokie numery na wynikach:

mysql> show profile context switches 
    -> ; 
+----------------------+-----------+-------------------+---------------------+ 
| Status    | Duration | Context_voluntary | Context_involuntary | 
+----------------------+-----------+-------------------+---------------------+ 
| (initialization)  | 0.000007 |     0 |     0 | 
| checking permissions | 0.000009 |     0 |     0 | 
| Opening tables  | 0.000045 |     0 |     0 | 
| System lock   | 0.000009 |     0 |     0 | 
| Table lock   | 0.000008 |     0 |     0 | 
| init     | 0.000056 |     0 |     0 | 
| Updating    | 46.063662 |    75487 |    14658 | 
| end     | 2.803943 |    5851 |     857 | 
| query end   | 0.000054 |     0 |     0 | 
| freeing items  | 0.000011 |     0 |     0 | 
| closing tables  | 0.000008 |     0 |     0 | 
| logging slow query | 0.000265 |     2 |     1 | 
+----------------------+-----------+-------------------+---------------------+ 
12 rows in set (0.00 sec) 

Tabela zawiera około 2,5 miliona rekordów, identyfikator jest kluczem podstawowym i ma jeden unikalny indeks na innym polu (nieuwzględnione w aktualizacji).

To stolik innodb.

Jakieś wskazówki na temat tego, co może być przyczyną?

Jakieś konkretne zmienne, które mogą pomóc w śledzeniu problemu?

Czy istnieje "wyjaśnienie" aktualizacji?

EDIT: Również Właśnie zauważyłem, że tabela zawiera również:

`modDate` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, 

Wyjaśnij:

+----+-------------+---------------+-------+---------------+---------+---------+-------+------+-------+ 
| id | select_type | table   | type | possible_keys | key  | key_len | ref | rows | Extra | 
+----+-------------+---------------+-------+---------------+---------+---------+-------+------+-------+ 
| 1 | SIMPLE  | table1  | const | PRIMARY  | PRIMARY | 8  | const | 1 |  | 
+----+-------------+---------------+-------+---------------+---------+---------+-------+------+-------+ 
1 row in set (0.02 sec) 
+0

Co to jest typ pól 'field1' i' id'? –

+1

Możesz spróbować profilować tę kolejkę. Zobacz http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html –

+0

Wygląda nieparzyste - dopasowano 1 wiersz, ale dotyczy to zerowych wierszy? –

Odpowiedz

8

Nie ma mowy, że zapytanie powinno trwać długo, jeśli id ​​jest naprawdę podstawowy klucz (chyba że masz dużo i dużo identyfikatorów równych 2229230?). Proszę uruchomić dwa następujące zapytania SQL i po wyniki:

show create table table1; 
explain select * from table1 where id = 2229230; 

Update: po prostu być kompletne, również zrobić

select count(*) from table1 where id = 2229230; 
+0

+1 z pewnością pomoże sprawdzić, czy istnieje niepoprawna definicja tabeli, czy rzuty w tych informacjach – Zak

4

Mogę polecić także:

OPTIMIZE TABLE table1; 

Czasami stoły po prostu potrzebują odrobiny miłości, jeśli szybko się rozrosły i nie zoptymalizowano ich od jakiegoś czasu, indeksy mogą być trochę szalone. W rzeczywistości, jeśli masz czas (i robią), to nigdy nie zaszkodzi dorzucić

REPAIR TABLE table1; 
+0

są sposobem na poznanie przed ręką, czy optymalizacja lub naprawa będzie Zrób coś ? lub ich uruchamianie jest jedyną opcją? – webclimber

+0

@webclimber - działa lokalnie. – Phil

4

ok po kilku godzinach tropienia ten, wydaje się, że przyczyną była „Duplikat indeksu” The utworzyć tabelę że robię odpowiedzieć Keitha, miał to dziwne combo:

  • unikalny klucz na fieldx
  • klawisza fieldx

drugi jest oczywiście zbędne i bezużyteczne, ale po tym jak spadam po naciśnięciu klawisza wszystkie aktualizacje powróciły do ​​< 1 sekunda.

+1 do Keitha i Ivana jako ich komentarze pomogły mi w końcu wyśledzić problem.

1

Pomogło mi zmienić silnik z "innodb" na "myisam". Moje zapytanie o aktualizację na zbiorze danych o podobnym rozmiarze zmieniło się z 100 ms na 0.1 ms.

Należy pamiętać, że zmiana typu silnika dla istniejącej aplikacji może mieć konsekwencje, ponieważ InnoDB ma lepszą integralność danych i niektóre funkcje mogą zależeć od aplikacji.

Dla mnie warto było stracić InnoDB na 1000-krotny wzrost prędkości na dużych zbiorach danych.

+2

Zmiana aplikacji z InnoDB na MyISAM może być niebezpieczna. MyISAM nie zapewnia niemal żadnych gwarancji integralności danych. –

+1

Dobra uwaga, dodam, że do mojej odpowiedzi, w przypadku, gdy aplikacja jest dokonywana przez osobę również ustawiającą typ silnika dobrze jest wiedzieć, że w niektórych przypadkach możliwe jest poświęcenie integralności danych dla prędkości. – Kapytanhook

0

Natknąłem się na tę samą kwestię, która okazała się być spowodowana wyzwalaczem na stole. Za każdym razem, gdy aktualizacja była wykonywana na mojej tabeli, wyzwalacz aktualizowałby kolejną tabelę, która była rzeczywiście spowodowana opóźnieniem. Dodanie indeksu do tej tabeli naprawiło problem. Więc spróbuj sprawdzić wyzwalacze na stole.

0

Inną kwestią, którą trzeba wziąć pod uwagę, gdy debugowanie instrukcji aktualizujących zajmuje zbyt dużo czasu w porównaniu do wersji instrukcji wyboru: to instrukcje aktualizacji wykonywane w ramach transakcji?

W moim przypadku transakcja przekształciła instrukcje aktualizacji z niesamowicie szybkiego czasu wykonania na bardzo wolny. Im więcej rzędów dotyczyło cięższej utraty wydajności. Moje instrukcje działają ze zmiennymi zdefiniowanymi przez użytkownika, ale nie wiem, czy ta część "problemu".