Mamy prostą aplikację internetową działającą na maszynie wirtualnej, która zapisuje swoje dane w bazie danych MySQL 5.5 za pomocą silnika InnoDB. Wszystko działało dobrze przez około trzy lata, ale nagle stało się bardzo wolne.
Na przykład mam bardzo prosty adres przechowujący tabelę:
CREATE TABLE `addresses` (
`address_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(64) CHARACTER SET latin1 NOT NULL,
`firstname` varchar(64) CHARACTER SET latin1 NOT NULL,
`street` varchar(64) CHARACTER SET latin1 NOT NULL,
`housenumber` varchar(16) CHARACTER SET latin1 NOT NULL,
`zip` varchar(5) CHARACTER SET latin1 NOT NULL,
`city` varchar(64) CHARACTER SET latin1 NOT NULL,
`email` varchar(64) CHARACTER SET latin1 NOT NULL,
`phone` varchar(16) CHARACTER SET latin1 NOT NULL,
`birthdate` date NOT NULL,
PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
Ta tabela zawiera około 800 wpisów, co naprawdę nie jest wiele. Ale uruchomienie zapytania
SELECT * FROM addresses
do celów testowych wydaje się, że nigdy się nie kończy. Sprawdziłem to za pomocą interfejsu mysql CLI na samym serwerze: wypisuje kilka wierszy tabeli, a następnie czeka bardzo długo, aż wypisze kolejne wiersze.
Być może jest to problem w fazie przesyłania danych, ale nie jestem pewien.
Maszyna wirtualna ma 2 GB pamięci RAM i wykorzystuje tylko 320 MB. Procesor działa również na bardzo niskim poziomie 1–2%. mytop nie wyświetla żadnych innych zapytań blokujących serwer. Administrator IT powiedział, że nic nie zmienili po stronie sprzętowej.
Próbowałem już czegoś takiego jak zrestartowanie serwera bazy danych, zrestartowanie maszyny wirtualnej. Nic nie pomogło.
edytować:
EXPLAIN SELECT * FROM addresses
daje mi ten wynik:
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | addresses | ALL | NULL | NULL | NULL | NULL | 793 | |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)
źródło
mysql -u username -ppassword mydb -e 'SELECT * FROM addresses
działa powoli, ale dołączając `> test.txt`, działa bardzo szybko. To prawdopodobnie byłoby inne pytanie !? Jak mogę to zbadać?Odpowiedzi:
Jeśli obciążenie procesora jest niskie, oznacza to, że nie ma problemów z brakującymi indeksami, w takim przypadku zapytanie wymagałoby tylko więcej procesora i dostępu do dysku. Powiedziałeś też, że działało dobrze przez 3 lata.
Czy sprawdziłeś ogólną szybkość dostępu do dysku (szczególnie na partycji, na której znajduje się baza danych)? Np. Używając
dd
jak tutaj . To, co opisujesz, brzmi jak martwy dysk lub na wpół martwy nalot. Mam nadzieję, że masz kopie zapasowe?źródło
Możesz spróbować kilku rzeczy,
Indeksowanie umożliwia szybkie wyszukiwanie rekordów bez uprzedniego pełnego skanowania tabeli, co znacznie skraca czas wykonywania.
W przypadku użycia przed zapytaniem SELECT opisuje, w jaki sposób MySQL zamierza wykonać zapytanie oraz liczbę wierszy, które będzie musiał przetworzyć przed jego zakończeniem.
Istnieje wiele optymalizatorów MySQL, które mogą cię poprowadzić.
Pomóż to pomaga
źródło
htop
pokazuje, że zużywa się tylko 307 MB z 2050 MB pamięci RAM.name
„imienia”. Po drugie, czy jesteś pewien, że indeksowanie przebiegło poprawnie? możliwy_klucz: NULL, jeśli kolumna ma wartość NULL, oznacza to, że nie można znaleźć odpowiednich indeksów.