1. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Daten möglichst schnell in MySQL importieren

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von slurp, 16 Mai 2013.

  1. slurp

    slurp Neuer Benutzer

    Hallo Zusammen.

    Ich bin ganz neu hier und ich hoffe ihr könnt mir Helfen :)

    Ich möchte Daten die ich habe (*.nq-Dateien) in MySQL importieren.
    Die Daten liegen im NQuads-Format vor und enthalten somit keine SQL-Insert-Statements, der mysqlimport-Befehl funktioniert daher nicht.
    Ich habe mir ein Java-Programm geschrieben, dass diese nq-Dateien parst (Zerlegung in einfache Token) und mittels prepared-Statement in die DB schreibt.
    Das Importieren von 5GB Daten dauert bei mir knapp über 2 Stunden :(

    Die DB wird nur lokal und somit von nur einem Benutzer genutzt. Ich verwende eine MyISAM und eine InnoDB Tabelle in die ich dieselben Daten schreibe.
    Der Flaschenhals in meinem Java-Programm ist die "execute()"-Anweisung des Prepared Statements. Wenn ich diese Anweisung auskommentiere benötigt das Programm knapp 1 Minute für die Ausführung.
    Ich suche nun nach einer Möglichkeit diese Daten möglichst schnell in die DB zu pumpen.

    Hier meine Tabellen:

    CREATE TABLE dbpedia_innodb (
    line INT NOT NULL AUTO_INCREMENT ,
    one VARCHAR(4000) NULL ,
    two VARCHAR(4000) NULL ,
    three LONGTEXT NULL ,
    four VARCHAR(4000) NULL ,
    PRIMARY KEY (line) )
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = latin1;

    CREATE TABLE dbpedia_myisam (
    line INT NOT NULL AUTO_INCREMENT ,
    one VARCHAR(4000) NULL ,
    two VARCHAR(4000) NULL ,
    three LONGTEXT NULL ,
    four VARCHAR(4000) NULL ,
    PRIMARY KEY (line) )
    ENGINE = MyISAM
    DEFAULT CHARACTER SET = latin1;

    Kann mir jemand sagen, wie ich die Daten möglichst schnell importiere? Welche Parameter muss ich setzen?
    Ich arbeite unter Linux mit MySQL 5.5. Während des Importvorgangs schaue ich mir mittels "iotop" die Festplattenauslastung an und sehe, dass lediglich nur ein paar MB/s oder teilweise nur KB/s in vom mysqld-Prozess geschrieben werden (Festplatte ist aber in Ordnung und schafft rund 90MB/s im Durschnitt). Die CPU-Auslastung liegt bei etwa 50%. Was bremst den Import hier so gewaltig? Ach ja: ich mache etwa alle 8000 Tupel einen Commit. Ist das bei MyISAM überhaupt notwendig?

    Vielen Dank das Ihr euch Zeit für mich nehmt!

    EDIT:
    Das prepared Statement besteht lediglich aus einem simplen "insert into tabelle(one, two,three) values (?,?,?)" also keine komplexe Anfrage.
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Schau Dir an, wie ein Dump aufgebaut ist. Das Format kannst Du mit LOAD DATA oder wie das bei MySQL sich nennt recht schnell laden. Alles andere dauert länger.
     
  3. ukulele

    ukulele Datenbank-Guru

    Für mich hört sich das schon nach einem sinnvollen Weg an aber da ich in MySQL sowas noch nie gemacht habe sehe ich da keinen Fehler und kenne leider auch keine Alternative.

    Trotzdem würde ich sicherheitshalber auf SQL Injection hinweisen, nicht das dein Parser da potenziellen Schadecode durchreicht.
     
  4. slurp

    slurp Neuer Benutzer

    Hallo Zusammen.

    Vielen Dank für Eure Antworten.

    @ukulele:
    Bzgl. SQL-Injection: Ich verwende ein Prepared Statement mit Parametern, soweit ich das sehe dürfte sich JDBC darum kümmern. Ich selbst baue keine Strings zusammen und übergebe diese an die DB. Trotzdem vielen Dank für den Hinweis!

    @akretschmer:
    Danke, kannte ich noch garnicht. Das scheint der richtige Weg zu sein, ein Import mittels "LOAD DATA INFILE" war wesentlich schneller: von etwa 2 Std auf knapp 3 Minuten :).
    Was mich hier jetzt quält ist die Frage wie LOAD DATA INFILE arbeitet. Schreibt es die DB-Datei selbst unter Umgehung der gesamten DBMS (nach einem table lock)? Ich weiß zwar, dass bei dieser Variante kein SQL geparst werden muss sondern nur die Daten weitergereicht werden müssen. Aber das dabei ein solcher Zeitunterschied auftritt ist doch recht merkwürdig.
    Wie sieht das eigentlich aus, wenn ich BULK-Daten (welche zur Laufzeit generiert werden) in die DB pumpen möchte. Ich müsste in einem solchen Fall dann die Daten vorerst in eine TXT-Datei appenden und dann zb. stündlich/täglich mittels "LOAD DATA INFILE" die Daten in die DB schreiben. Das sieht allerdings sehr unschön aus, dürfte aber wesentlich schneller gehen.

    Viele Grüße
     
  5. akretschmer

    akretschmer Datenbank-Guru

    Ich weiß nicht, wie MySQL da vorgeht. In PostgreSQL nennt sich das vergleichbare Vorgehen COPY, und da gibt es *keinerlei* Sperren. MVCC. Hängt bei MySQL möglicherweise auch von der Engine ab.

    Andreas
     
  6. Margit

    Margit Fleissiger Benutzer Mitarbeiter

Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden