2016-03-20 6 views
0

Warum die Abfrageleistung stark sinkt, wenn ich die Abfrage "INSERT ALL" größer als etwa 600 Datensätze in Oracle verwende? Können Sie mir beibringen?Warum die Abfrageleistung stark sinkt, wenn Datensätze> ungefähr 600

Ich verwende Spring + Mybatis + Oracle

Es folgt meiner Anfrage.

INSERT ALL 
    <foreach collection="list" item="record"> 
     INTO tablename (
     a, 
     b, 
     c, 
     d, 
     e, 
     f, 
     g, 
     h, 
     i, 
     j, 
     k, 
     l, 
     m, 
     n, 
     o 
    ) VALUES (
     #{a}, 
     #{b}, 
     #{c}, 
     #{d}, 
     #{e}, 
     #{f}, 
     #{g}, 
     #{h}, 
     #{i}, 
     #{j}, 
     #{k}, 
     #{l}, 
     #{m}, 
     #{n}, 
     #{o} 
    ) 
    </foreach> 
    SELECT 1 FROM dual 

(I geändert Spalte und den Namen der Variablen. Ober Abfrage funktioniert)

Bitte helfen Sie mir ~

+2

Das erste, was ich versuchen würde, um herauszufinden, was das Problem ist: Führen Sie die Fragen Sie in Ihrem Oracle Developer (oder dem von Ihnen verwendeten Tool) nach, ob es dort auch langsam ist. Wenn ja, dann ist das Problem Ihre Anfrage. Wenn nicht, ist das Problem auf der Java-Seite. –

+0

@FlorianSchaetz Ich habe die obere Abfrage in Oracle Developer ausgeführt, und die Leistung war nicht schlecht (natürlich habe ich "INTO Satz" mehr als 600 Mal ohne mybatis kopiert). Also habe ich es in JAVA "ohne Mybatis" versucht und die Leistung war gut genug. Ich denke, mybatis kann ein Problem sein. Vielen Dank! Ihr Kommentar war hilfreich. –

+0

Völlig möglich, schwer zu sagen, ohne es wirklich zu profilieren. Aktivierungsprotokollierung wäre ein erster Schritt, um zu sehen, wo es langsam wird, der nächste würde Profiling sein. –

Antwort

2

Als @Kordirko erwähnt, ist es wahrscheinlich am langsamsten, weil Ihre Verwendung von MyBatis einfügen Batching nicht tut.

Dies ist mehrreihigen Einsatz Beispiel from MyBatis docs:

<insert id="insertAuthor" useGeneratedKeys="true" 
    keyProperty="id"> 
    insert into Author (username, password, email, bio) values 
    <foreach item="item" collection="list" separator=","> 
    (#{item.username}, #{item.password}, #{item.email}, #{item.bio}) 
    </foreach> 
</insert> 

So versuchen, es auf diese Weise zu nutzen:

INSERT INTO tablename (
    a, 
    b, 
    c, 
    d, 
    e, 
    f, 
    g, 
    h, 
    i, 
    j, 
    k, 
    l, 
    m, 
    n, 
    o 
) VALUES 
    <foreach collection="list" item="record"> 
    (
    #{a}, 
    #{b}, 
    #{c}, 
    #{d}, 
    #{e}, 
    #{f}, 
    #{g}, 
    #{h}, 
    #{i}, 
    #{j}, 
    #{k}, 
    #{l}, 
    #{m}, 
    #{n}, 
    #{o} 
) 
</foreach> 
-1

Der Grund schwer zu sagen ist. Die Größe des Kommunikationsblocks, die Größe Ihres Oracle-Prozesses, die Art Ihrer Verbindung, die Speicherkonfiguration der Oracle-Datenbank, die Sie verwenden, und viele andere.

Aber eine andere Frage ist, warum Sie im Wesentlichen Transaktionsverarbeitung für Batch (Bulk) verwandte Arbeit verwenden. Wenn man mit 600 Reihen auf diese Mauer trifft, sei eine Ausnahme, lebe damit. Wenn Sie dies für eine große Anzahl von Zeilen (viele tausend) benötigen und oft, dann schauen Sie sich Batch-Verarbeitungstechniken an.

Bleiben Sie weg von XML und wahrscheinlich objektorientierten Techniken. Verwenden Sie Tools als ftp, um Ihre Datenmenge auf den Datenbankserver zu übertragen. Verwenden Sie externe Tabellen oder sql Loader, um Ihre Daten in die Datenbank zu bekommen. (Verwenden Sie nicht den sql Loader über eine Netzwerkverbindung, die Netzwerklatenz wird Ihre Leistung zerstören !!). Verwenden Sie gespeicherte Prozeduren für die weitere Verarbeitung.

Verwandte Themen