Mam tabelę z 1,4 miliarda rekordów. Struktura tabeli jest następująca:
CREATE TABLE text_page (
text VARCHAR(255),
page_id INT UNSIGNED
) ENGINE=MYISAM DEFAULT CHARSET=ascii
Wymagane jest utworzenie indeksu nad kolumną text
.
Rozmiar stołu wynosi około 34G.
Próbowałem utworzyć indeks za pomocą następującej instrukcji:
ALTER TABLE text_page ADD KEY ix_text (text)
Po 10 godzinach oczekiwania w końcu zrezygnowałem z tego podejścia.
Czy istnieje jakieś realne rozwiązanie tego problemu?
AKTUALIZACJA : jest mało prawdopodobne, że tabela zostanie zaktualizowana, wstawiona lub usunięta. Powodem, dla którego należy utworzyć indeks w kolumnie, text
jest to, że tego rodzaju zapytania SQL byłyby często wykonywane:
SELECT page_id FROM text_page WHERE text = ?
AKTUALIZACJA : Rozwiązałem problem, dzieląc tabelę na partycje.
Stół jest podzielony na 40 części na kolumnie text
. Następnie utworzenie indeksu na stole zajmuje około 1 godziny.
Wydaje się, że tworzenie indeksu MySQL staje się bardzo wolne, gdy rozmiar tabeli staje się bardzo duży. Partycjonowanie zmniejsza tabelę na mniejsze pnie.
CREATE INDEX
stwierdzenia?Odpowiedzi:
Czy to możliwe, że Twój system po prostu nie spełnia tego zadania? Nie używam MySQL (tutaj SQL Server), ale znam ból związany z indeksowaniem 800 milionów wpisów. Zasadniczo ... potrzebujesz do tego odpowiedniego sprzętu (jak w: wiele szybkich dysków). Używam teraz prawie tuzina Velociraptorów, a wydajność jest świetna;)
Serwery SQL (nie jako MS SQL Server, ale jako serwery baz danych używające SQL) żyją i umierają z dostępem do dysku, a normalne dyski po prostu nie są w stanie wykonać większych operacji.
źródło
Możesz utworzyć indeks dla pierwszych (na przykład 10) znaków w polu tekstowym.
Z Dokumentów:
Można tworzyć indeksy, które wykorzystują tylko wiodącą część wartości kolumn, używając składni nazwa_kolumny (długość) do określenia długości prefiksu indeksu:
źródło
Rozwiązałem problem, dzieląc tabelę.
Stół jest podzielony na 40 części na kolumnie
text
. Następnie utworzenie indeksu na stole zajmuje około 1 godziny.Wydaje się, że tworzenie indeksu MySQL staje się bardzo wolne, gdy rozmiar tabeli staje się bardzo duży. Partycjonowanie zmniejsza tabelę na mniejsze pnie.
źródło
Ustaw sort_buffer_size na 4 GB (lub tyle, ile możesz, w zależności od ilości dostępnej pamięci).
W tej chwili indeks tworzenia wykonuje sortowanie, ale ponieważ masz 32 MB sort_buffer_size, to w zasadzie niepotrzebnie wyrzuca dysk twardy.
źródło
Jeśli nie musisz wykonywać takich zapytań jak:
Sugerowałbym utworzenie nowej kolumny mieszającej i indeksowanie tabeli według kolumny. Całkowity rozmiar tabeli + indeksu może być znacznie mniejszy.
UPD : Nawiasem mówiąc, 1,4 miliarda liczb całkowitych klucza podstawowego zajmuje około 6 GB, co oznacza, że średnia długość łańcucha jest mniejsza niż 30 znaków, więc indeksowanie na prefiksie może być bardziej korzystne.
Powinieneś także spojrzeć na silnik pamięci masowej MERGE .
źródło
Jednym ze sposobów jest utworzenie nowej tabeli z zestawem indeksów i skopiowanie danych do nowej tabeli.
Upewnij się także, że masz wystarczającą ilość miejsca na temp.
źródło
Jeśli nadal zastanawiasz się, jak to zrobić najlepiej, sugeruję skorzystanie z internetowego narzędzia do zmiany tabeli.
W Internecie jest ich wiele, jedną ze znanych jest:
http://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html
Mamy te same problemy z dużymi tabelami (ponad 500 mil rekordów) i przeróbka przebiega idealnie. Tworzy nową tabelę tmp, dodaje wyzwalacz do oryginalnej tabeli (dla nowych aktualizacji / usuwania / wstawiania rekordów), a tymczasem kopiuje wszystkie rekordy do nowej tabeli (z nową strukturą)
Powodzenia!
źródło