Jeg eksperimenterede lidt med dette koncept på et tidligere job, hvor vi havde brug for en hurtig metode til at kopiere skemaer mellem MySQL-servere.
Der er faktisk en ydeevne overhead, når du indsætter til tabeller, der har sekundære indekser. Indsæt skal opdatere det klyngede indeks (også kaldet tabellen), og også opdatere sekundære indekser. Jo flere indekser en tabel har, jo mere overhead forårsager den for indsættelser.
InnoDB har en funktion kaldet ændringsbuffer hvilket hjælper lidt ved at udskyde indeksopdateringer, men de skal slås sammen til sidst.
Indsættelser til en tabel uden sekundære indekser er hurtigere, så det er fristende at forsøge at udskyde oprettelsen af indeks, indtil efter dine data er indlæst, som du beskriver.
Percona Server, en gren af MySQL, eksperimenterede med en mysqldump --optimize-keys
mulighed. Når du bruger denne mulighed, ændrer den outputtet af mysqldump til at have CREATE TABLE uden indekser, derefter INSERT alle data og derefter ALTER TABLE for at tilføje indekserne, efter at dataene er indlæst. Se https://www.percona.com/doc/ percona-server/SENESTE/management/innodb_expanded_fast_index_creation.html
Men efter min erfaring var nettoforbedringen i ydeevne lille. Det tager stadig et stykke tid at indsætte mange rækker, selv for tabeller uden indeks. Derefter skal gendannelsen køre en ALTER TABLE for at bygge indekserne. Dette tager et stykke tid for et stort bord. Når du tæller tiden for INSERT plus den ekstra tid til at bygge indekser, er det kun et par (lavt encifrede) procent hurtigere end at indsætte den traditionelle måde i en tabel med indekser.
En anden fordel ved denne efterbehandlingsindeksoprettelse er, at indekserne gemmes mere kompakt, så hvis du har brug for at spare diskplads, er det en bedre grund til at bruge denne teknik.
Jeg fandt det meget mere fordelagtigt for ydeevnen at genoprette ved at indlæse flere tabeller parallelt .
- Det nye MySQL 8.0-værktøj mysqlpump understøtter multi-threaded dump.
- Open source-værktøjet mydumper
understøtter multi-threaded dump, og har også et multi-threaded gendannelsesværktøj, kaldet
myloader
. Den værste ulempe ved mydumper/myloader er, at dokumentationen stort set ikke eksisterer, så du skal være en uforfærdet superbruger for at finde ud af, hvordan du kører den.
En anden strategi er at bruge mysqldump --tab
at dumpe CSV-filer i stedet for SQL-scripts. Masseindlæsning af CSV-filer er meget hurtigere end at udføre SQL-scripts for at gendanne dataene. Nå, det dumper en SQL-fil til tabeldefinitionen og en CSV for de data, der skal importeres. Det opretter separate filer for hver tabel. Du skal manuelt genskabe tabellerne ved at indlæse alle SQL-filerne (dette er hurtigt), og derefter bruge mysqlimport
for at indlæse CSV-datafilerne. Mysqlimport-værktøjet har endda en --use-threads
mulighed for parallel udførelse.
Test omhyggeligt med forskellige antal parallelle gevind. Min erfaring er, at 4 tråde er bedst. Med større parallelitet bliver InnoDB en flaskehals. Men din oplevelse kan være anderledes, afhængigt af versionen af MySQL og din serverhardwares ydeevne.
Den hurtigste gendannelsesmetode af alle er, når du bruger et fysisk sikkerhedskopieringsværktøj, den mest populære er Percona XtraBackup . Dette giver mulighed for hurtige sikkerhedskopier og endnu hurtigere gendannelser. De sikkerhedskopierede filer er bogstaveligt talt klar til at blive kopieret på plads og brugt som live tablespace-filer. Ulempen er, at du skal lukke din MySQL-server ned for at udføre gendannelsen.