Mamy tabelę mysql, która w danym momencie ma około 12 milionów wierszy. Musimy usunąć stare dane, aby wielkość tabeli była w pewnym stopniu zarządzalna.
Obecnie uruchamiamy to zapytanie codziennie o północy, używając zadania cron:
DELETE FROM table WHERE endTime < '1393632001'
Podczas ostatniego uruchomienia zapytania zbadano 4,602,400, zajęło to ponad 3 minuty, a procesor przeszedł przez dach.
Co możemy zrobić, aby procesor, synchroniczne połączenia db, głębokość pamięci dyskowej itp. Nie powodowały nadmiernego skakania przy jednoczesnym usuwaniu starych danych?
PS: Zauważysz, że zapytanie faktycznie dzieje się w dość nieodpowiednim czasie w naszym cyklu użytkowania. Załóżmy, że zmieniliśmy już czas zapytania, tak aby pojawiał się w najniższym punkcie użycia każdego dnia. Poza tym nie ma indeksu na „endTime” i wolałbym go tak utrzymywać, jeśli to możliwe, ponieważ bardzo często wstawianych jest mnóstwo danych i niewiele wyszukiwania.
Odpowiedzi:
Rozwiązaniem Twojego problemu jest funkcja MySQL zwana „partycjonowaniem”. Dokumentacja jest tutaj .
Partycjonowanie polega na przechowywaniu pojedynczej tabeli w osobnych „partycjach”. Są one zdefiniowane przez określone wyrażenie, zwykle wartość kolumny lub zakres. W twoim przypadku prawdopodobnie byłoby to oparte na
endTime
- zakładając, że wiadomo, kiedy rekord jest tworzony i nie ulega zmianie.W
endTime
każdej partycji można zapisać wartość jednego dnia . Następnie krok usuwania oznaczałby obcięcie partycji, a nie usunięcie szeregu wierszy w dużej tabeli. Obcinanie partycji byłoby znacznie szybszą metodą.źródło