Wyłączone klawisze MySqlDump nie mają wpływu na import

10

Kontynuuję moje poprzednie pytanie dotyczące prędkości importu w Inno-Tables (niespodzianka!).

Scenariusz
Próbuję zaimportować duży * zrzut bazy danych na mój lokalny komputer programistyczny w rozsądnym czasie. Mamy wiele KEYzałączonych tabel, które okazały się wąskim gardłem, ale nadal są ważne dla naszego systemu na żywo.

Moje podejście po zadaniu powyższego pytania polegało na usunięciu KEY ...instrukcji ze zrzutów, importowaniu i ponownym dodawaniu kluczy.

Jednak często zdarza mi się edytować bieżący zrzut, aby zaimportować go lokalnie, i natknąłem się na te śmieszne „komentarze” (The disable/enable keys-lines)

--
-- Dumping data for table `monster`
--

LOCK TABLES `monster` WRITE;
/*!40000 ALTER TABLE `monster` DISABLE KEYS */;
INSERT  INSERT  INSERT
/*!40000 ALTER TABLE `monster` ENABLE KEYS */;
UNLOCK TABLES;

Ale w rzeczywistości te „komentarze” są warunkowymi oświadczeniami MySql

To była dla mnie nowość, ale ok, biorąc pod uwagę wynik, mysql --versionże wszystko wygląda dla mnie dobrze: mysql Ver 14.14 Distrib 5.5.38, for debian-linux-gnu (x86_64) using readline 6.3

Co zakładam
Stół jest zamknięty (w porządku, to tylko ja na urządzeniu deweloperskim). Następnie klucze zdefiniowane w schemacie tabeli są wyłączane, dane są importowane, klucze są włączane.
Dlatego podczas fazy „wstawiania danych” klucze nie powinny tracić czasu, a raczej sprawdzane po wstawieniu wszystkich danych.

Pomyślałbym, że jest to takie samo zachowanie, jak gdybym usunął wszystkie KEY 'foo' (foo)'linie z zrzutu, zaimportowałem zrzut i uruchomiłem ADD KEY 'foo' ...później skrypt .

Co obserwuję
Jest znacznie szybsze ręczne usuwanie kluczy, importowanie i ponowne dodawanie kluczy, a następnie poleganie na DISABLE KEYSinstrukcjach warunkowych utworzonych przeze mniemysqldump

Ręczna edycja zrzutu + importu MySQL + dodawanie kluczy = 15 + 8 + 8 ≈ 30min
Zwykły import MySQL: zrezygnowałem, (dostaję zapłatę za 8 godzin dziennie> :))

Nie mogę przestać myśleć, że brakuje mi czegoś bardzo podstawowego (lub trolluje mnie baza danych).

nuala
źródło
2
Krótkoterminowa: korzystanie mysqldump --innodb-optimize-keysz Percona percona.com/doc/percona-server/5.5/management/... długoterminowa zaprzestać używania mysqldump i używać mydumper lub xtrabackup.
jynus

Odpowiedzi:

12

Nie można powoływać się na DISABLE KEYS;i ENABLE KEYS;dla InnoDB, ponieważ nie jest on zaimplementowany w Storage Engine InnoDB. Uruchamianie ALTER TABLE ... DISABLE KEYS;i ALTER TABLE ... ENABLE KEYS;zostały zaprojektowane dla MyISAM. Jak napisano w dokumentacji MySQL dlaALTER TABLE :

Jeśli użyjesz ALTER TABLE w tabeli MyISAM, wszystkie nieunikalne indeksy są tworzone w osobnej partii (jak w przypadku TABELI NAPRAW). To powinno sprawić, że ALTER TABLE będzie znacznie szybszy, gdy masz wiele indeksów.

W przypadku tabel MyISAM aktualizacja klucza może być kontrolowana jawnie. Użyj ALTER TABLE ... DISABLE KEYS, aby powiedzieć MySQL, aby przestał aktualizować indeksy niepowtarzalne. Następnie użyj ZMIEŃ TABELĘ ... WŁĄCZ KLUCZE, aby odtworzyć brakujące indeksy. MyISAM robi to za pomocą specjalnego algorytmu, który jest znacznie szybszy niż wstawianie kluczy jeden po drugim, więc wyłączenie kluczy przed wykonaniem operacji wstawiania zbiorczego powinno znacznie przyspieszyć. Korzystanie z ALTER TABLE ... DISABLE KEYS wymaga uprawnień INDEX oprócz uprawnień wspomnianych wcześniej.

Chociaż indeksy niepowtarzalne są wyłączone, są one ignorowane dla instrukcji takich jak SELECT i EXPLAIN, które w przeciwnym razie by ich użyły.

Nigdy nie wspomniano o InnoDB w kontekście ALTER TABLE ... DISABLE/ENABLE KEYS;

Nawet jeśli uruchomisz ALTER TABLE ... DISABLE KEYS;tabelę InnoDB, wygeneruje ostrzeżenie:

mysql> show create table mytimes\G
*************************** 1. row ***************************
       Table: mytimes
Create Table: CREATE TABLE `mytimes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `totalTime` int(11) NOT NULL,
  `totalTimeDesc` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> alter table mytimes disable keys;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show warnings;
+-------+------+-------------------------------------------------------------+
| Level | Code | Message                                                     |
+-------+------+-------------------------------------------------------------+
| Note  | 1031 | Table storage engine for 'mytimes' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

Dlatego nie ma wpływu. Przypomnij sobie, że @jynus wspomniał o tym samym w swojej odpowiedzi w punkcie 7 .

Należy również pamiętać, że MyISAM przechowuje dane i indeksy w dwóch osobnych plikach (.MYD dla danych, .MYI dla indeksów), więc wyłączenie i włączenie indeksów byłoby trywialne. InnoDB zachowuje KLUCZ PODSTAWOWY i dane wiersza na tych samych stronach InnoDB (poprzez Indeks klastrowany). Indeksy wtórne będą nosić KLUCZ PODSTAWOWY jako załącznik do każdego wpisu liścia indeksu wtórnego . Ponieważ dane i indeksy są powiązane przez Indeks klastrowany, nikt jak dotąd nie próbował wdrożyć DISABLE KEYSani ENABLE KEYSw InnoDB.

RolandoMySQLDBA
źródło
1
„Mówiłem ci” :-)
jynus
@jynus HA HA :-). Jako odpowiedź powinieneś opublikować swój komentarz mysqldump dla InnoDB ( dba.stackexchange.com/questions/76565/… ).
RolandoMySQLDBA
@yoshi Piszę artykuł na podstawie twojego oryginalnego pytania, bądź na bieżąco.
jynus
@yosi Zgodnie z obietnicą: dbahire.com/…
jynus
@RolandoMySQLDBA, jeśli InnoDB nie może wykonać włączania / wyłączania kluczy, czy nie powinno to dawać błędu zamiast zwykłego ostrzeżenia?
Pacerier