2012-06-06 13 views
11

GISTPonowne indeksowanie ogromna baza danych (angielska Wikipedia) skutecznie

Przed wykonaniem masywny 40+ GB import angielskiej Wikipedii, musiałem tymczasowo usunąć indeksy i pola automatycznego przyrostu z trzech tabel ("strona", "rewizja" i "tekst") do obsługi obciążenia. Teraz udało mi się w końcu zaimportować angielską Wikipedię na mój komputer lokalny i utworzyć lokalne odbicie (MediaWiki API). Yay!

Jednak teraz muszę ponownie utworzyć indeksy i pola automatycznego zwiększania w mniej niż dekadę. Na szczęście (1) wykonałem wiele zrzutów ekranowych odpowiednich tabel w phpmyadminie, zanim usunąłem indeksy i pola; (2) Mogę z niezwykłą precyzją wyjaśnić kroki podjęte przed importem; i (3) nie powinno to być zbyt trudne dla osób biegle posługujących się MySQL. Niestety, nie mam żadnej wiedzy na temat MySQL, więc wyjaśnienia "baby steps" byłyby niezwykle pomocne.

właśnie zrobiłem (przygotowanie przez import):

krokach 1, 2, 3: To zdjęcie przedstawia tabela strona zanim zmodyfikowane pole page_id klikając 'Zmień' i un-checking "Auto-inkrementacja" (w przygotowaniu do importu). Przeprowadziłem dokładnie te same zmiany w polu rev_id w tabeli rewizja i old_id w tabeli tekst ale pominięto te zrzuty ekranowe, aby uniknąć zwolnień.

table 'page' before modification of 'page_id'

Krok 4: To zdjęcie przedstawia indeksów dla tabeli stronie zanim rzuciłem je wszystkie.

indexes for table 'page' before I dropped them

Krok 5: To zdjęcie przedstawia indeksów dla tabeli rewizji zanim rzuciłem je wszystkie.

indexes for table 'revision' before I dropped them

Krok 6: Ten obraz przedstawia indeksów dla tekstu stół zanim rzuciłem je wszystkie.

indexes for table 'text' before I dropped them

co muszę TERAZ (przywrócenie po przywozie):

po prostu trzeba przywrócić oryginalne indeksy i pola automatycznego przyrostu bez czekania sto lat.

Set-up szczegóły: PHP 5.3.8 (apache2handler), MySQL 5.5.16 (InnoDB), Apache 2.2.21, Ubuntu 12.04 LTS, MediaWiki 1.19.0 (prywatny wiki)

+1

+1 za dobrze napisane pytanie, ale obawiam się, że przy zbiorach danych tej wielkości tworzenie indeksów potrwa chwilę, bez względu na to, jak to zrobisz. Jeśli był to MyISAM, mógłbyś uniknąć przedrzucenia indeksów przed importowaniem: w tabelach MyISAM możesz je wyłączyć i włączyć ponownie po zakończeniu importowania danych, w takim przypadku MySQL automatycznie naprawi indeks przez sortowanie. Ale nawet wtedy, sortowanie 40 g danych zajmie trochę czasu nawet w szybkim systemie. I używasz InnoDB, w którym to nie jest możliwość AFAIK. – Daan

+0

Nie sądzę, że wyłączanie i włączanie jest szybsze niż tworzenie nowego indeksu. Zaczynasz od zera, sortuj dane i napisz indeks. – usr

+0

Pamiętaj, że jestem kompletnym początkującym MySQL. Wiem, co zrobiłem, ale nie mam pojęcia, jak sortować, ponownie indeksować itd., Więc byłoby bardzo pomocne, gdybyś wyjaśnił kod. Jeśli okaże się, że wyłączenie i aktywacja za pomocą MyISAM spowodowało ponowne indeksowanie drastycznie szybsze, zawsze mogłem odbudować wszystko od zera - robiłem to już wiele razy, mogłem z łatwością zrobić to ponownie za około 5 godzin. Najważniejsze jest to, że prawie nic nie wiem na temat MySQL, więc proszę o podanie konkretnych i dostarczenie przykładów kodu, jeśli to możliwe. –

Odpowiedz

4

naprawdę jak Wikipedia więc spróbuję pomóc.

trzeba używać dużo

ALTER TABLE 

Dodaj kluczy podstawowych

ALTER TABLE page ADD PRIMARY KEY (page_id); 
ALTER TABLE revision ADD PRIMARY KEY (rev_id); 
ALTER TABLE text ADD PRIMARY KEY (old_id); 

Dodaj przyrosty auto z powrotem

ALTER TABLE page MODIFY COLUMN page_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT; 

muszę opisy tabel dla wszystkich tabel przed kontynuowaniem. Jeśli rev_id i old_id są same definicje jak page_id następnie:

ALTER TABLE revision MODIFY COLUMN rev_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT; 
ALTER TABLE text MODIFY COLUMN old_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT; 

Dodaj unikatowych kluczy

ALTER TABLE page ADD UNIQUE name_title(page_namespace, page_title); 
ALTER TABLE revision ADD UNIQUE rev_page_id(rev_page, rev_id); 

Inne indeksy

ALTER TABLE page ADD INDEX page_random(page_random); 
ALTER TABLE page ADD INDEX page_len(page_len); 
ALTER TABLE page ADD INDEX page_redirect_namespace(page_is_redirect, page_namespace, page_len); 
ALTER TABLE revision ADD INDEX rev_timestamp(rev_timestamp); 
ALTER TABLE revision ADD INDEX page_timestamp(rev_page, rev_timestamp); 
ALTER TABLE revision ADD INDEX user_timestamp(rev_user, rev_timestamp); 
ALTER TABLE revision ADD INDEX user_text_timestamp(rev_user_text, rev_timestamp); 

Znowu, nie może być kolumna definicje, które zmieniają te rzeczy. Musisz podać informacje o CREATE TABLE.

+0

Czy to masz na myśli? To jest tabela zmian http://imageshack.us/photo/my-images/38/revid.png/, a tabela tekstowa jest widoczna u góry strony http://imageshack.us/photo/my-images/ 59/textindex.png/ Jeśli nie, to gdzie powinienem wyglądać? Mam mnóstwo innych zrzutów ekranu. –

+2

@BrianSchmitz Yup dokonał kilku zmian i teraz wszystko powinno działać. W przyszłości użyj "POKAŻ STWÓR TABELI nazwa_tabeli" zamiast zrzutów ekranu phpmyadmin. – saccharine

+0

Doskonały. Spodziewam się, że ponowne indeksowanie powinno zająć trochę czasu, ale czy byłbyś w stanie zrobić bardzo, bardzo szorstki plan gry w piłkę o wielkości rzędu czasu przetwarzania, o którym tutaj mówimy? Godziny? Dni? (Robię wszystko na dość zgrabnym laptopie.) Jeśli nie, rozumiem, ponieważ wiem, że nie dostarczyłem zbyt wielu informacji. –