Select vs Update ins blaue, was ist teurer?

OnDemand

Top Contributor
Hallo zusammen,

versuch grad heraus zu finden, was in meinem folgenden Szenario DB lastiger ist um die DB nicht unnötig zu belasten.

Ich habe eine List mit 5000 Datensätzen aus einer Text-Datei, diese 5000 Objekte sind bereits in der Datenbank und müssen updated werden.
Sagen wir es sind 5000 Autos, jeweils muss der Preis updated werden (um es einfach zu halten, es werden noch wesentlich mehr Merkmale updated) und es muss ein Flag gesetzt werden, ob der Wagen noch in der Datei ist.

Nun die Frage, was ist "teurer" Jedes Auto einzeln erst mit Select holen, dann prüfen ob der Preis, Lagermenge, Lagerort etc geändert hat, wenn ja > updaten oder ist es schlauer direkt den Update Query absetzen und dabei auch gleich isavailable = true setzen?

Ich vermute, dass es die DB doppelt belastet wenn das Objekt erst geholt wird und dann nochmal updated wird oder?

Ich versuch es hier nochmal mit Dummycode darzustellen:

Plan A: Jedes Auto per select erstmal anfragen und während dessen als "Auto ist noch in der Textdatei" markieren.
Code:
void arbeiteTextDateiab() {

    updateAvailable();

    List<Auto> autos = leseDatei();
    for (Auto autoAusDatei : autos) {
        Auto existingAuto = getExistingAutoAusDb(autoAusDatei.id);
        if (existingAuto != null) {
            if (existingAuto.gerPreis() != autoAusDatei.getPreis()) {
                updatePrice();
            }
        }
          //else {
          //nichts machen, weil keine Änderung
         // }
    }


updateAvailable(){
Update auto set isavailable = false; //Alle Autos erstmal als nicht verfügbar markieren, wird dann auf true gesetzt, wenn es abgefragt wird. Alle die nach dem durchlauf immer noch false sind, sind werden deaktiviert, da sie nicht mehr in der Datei waren.
}

getExistingAutoAusDb(int id) {
    Select * from auto where id = id;
    Update auto set isavailable = true where id = id;
}

lesedatei() {
//Lese Datei
    return List < Auto >;
}

Plan B:
Auto einfach auf gut Glück updaten:
Code:
 List<Auto> autos = leseDatei();
    for(Auto autoAusDatei :autos){
        updatePrice(autoAusDatei);
    }

    updatePrice(Auto autoAusDatei){
        Update auto set price = autoAusDatei.getPreis(), SET isavailable=true WHERE id= autoAusDatei.getId();
    }

    lesedatei() {
        //Lese Datei
        return List < Auto >;
    }

    updateAvailable() {
        Update auto set isavailable = false; //Alle Autos erstmal als nicht verfügbar markieren, wird dann auf true gesetzt, wenn es abgefragt wird. Alle die nach dem durchlauf immer noch false sind, sind werden deaktiviert, da sie nicht mehr in der Datei waren.
    }
 

httpdigest

Top Contributor
Am schnellsten sind parametrisierte JDBC PreparedStatements zusammen mit JDBC Batch Updates. Google das am besten mal. Ich habe ein Projekt, bei dem das Aktualisieren von 138.000 Datensätzen mit ca. 10 Spalten in unter 5 Sekunden passiert.
JDBC PreparedStatements sorgen dafür, dass der JDBC-Treiber das SQL nicht bei jedem Update parsen und die Datenbank nicht jedesmal ein Execution Plan zu erzeugen braucht und Batch Update sorgt dafür, dass nicht für jedes Update ein Netzwerk-Request gesendet wird.
 

OnDemand

Top Contributor
Top, danke! Was mir da spontan (ohne tieferes Prüfen) noch in den Sinn kommt; ich muss auch "Autos" anlegen, wenn diese nicht in der DB sind. Daher meine Überlegung erstmal den Updatequery zu senden, wenn ich 1 zurück gekomme, wurde das Auto updated, wenn ich 0 zurück bekomme ist es noch nicht drin und ich muss es anlegen. Wie könnte man das in Verbindung mit Batch machen?
 

Wurstkopp

Bekanntes Mitglied
Grundsätzlich würde ich wenn es um Performance geht immer versuchen wenige große IO Operationen durchzuführen statt viele kleine. Also in diesem Fall erstmal alle in Frage kommenden Autos in den Speicher laden, dort dann im Code deine Logiken ausführen und anhand dieser eigene Listen für die verschiedenen Updatetypen aufbauen. Also eine Liste die geupdated werden müssen, eine Liste die neu angelegt werden soll, welche gelöscht werden sollen usw. Diese Listen werden dann erst am Ende wie bereits beschrieben mit den PreparedStatements zur Datenbank gefeuert.

Das hat natürlich auch Nachteile, weshalb man das Vorgehen nicht pauschal als das beste bezeichnen kann. Wenn du z.B. vorher nicht weißt, welche Daten (In dem Fall Autos) du denn aus der Datenbank brauchst. Wenn die DB sagen wir mal 5.000.000 Autos hat und du in deiner Liste für gewöhnlich nur 5.000 zufällige hast, dann ist das sehr ineffektiv. Auch ist der RAM Bedarf je nach Datenmenge sehr hoch. Man muss das also im Zweifel je nach Fall weiter optimieren. In der Praxis hatte ich damit aber meist sehr gute Ergebnisse.
 

OnDemand

Top Contributor
@httpdigest danke für den Tipp mit dem Prepared Statement! Der war gold wert. 5000 Updates in 20 Sek. Auf dem Livesystem gehts sicher noch schneller, die Verbindung von Test zur externen DB ist etwas lahm. Gibt es hier was einzuwenden? Das schließen der Session ist richtig oder?
Ich hole mir die Connection über den EntityManager da wir Hibernate im Einsatz haben und die DB Tenant aufgebaut ist, daher komm ich nicht wirklich anders an die reine Connection.

Code:
public void updateAuto(@RequestHeader("tenant") String tenant, @RequestBody List<Auto> autos) {
        TenantContext.setCurrentTenant(tenant);
        try {
            Session hibernateSession = em.unwrap(Session.class);
            hibernateSession.doWork(new org.hibernate.jdbc.Work() {

                @Override
                public void execute(Connection connection) throws SQLException {
                    PreparedStatement ps = connection
                            .prepareStatement("update auto set xxx=?, WHERE id=?");

                    for(Auto auto : autos){
                        ps.setInt(1, auto.getXxx());
                        ps.setString(2,auto.getId());
                        ps.addBatch();
                    }
                    ps.executeBatch();
                }
            });
            hibernateSession.close();
        } catch (Exception e) {
            log.error("Error : " + tenant, e);
        }
 

mrBrown

Super-Moderator
Mitarbeiter
Wenn du noch nie Spring Data JPA genutzt hast würd ich mich nicht deswegen darin einarbeiten, wag nur als Hinweis gedacht, dass man nicht nur wegen Batch Update darauf verzichten muss ;)
 

OnDemand

Top Contributor
Hallo nochmal, wenn ich wie im Code siehe #7 den EM nutze, muss ich den closen?
Ich bekomme nämlich an anderer Stelle in der Klasse keine Verbindung mehr zur DB. Mit close wird es wohl endgültig geschlossen uns aus dem Pool entfernt. Kann ich die Verbindung "zurückgeben" oder soll ich einfach nichts machen und das Framework kümmert sich drum?
Caused by: java.lang.IllegalStateException: Session/EntityManager is closed
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S PostgreSQL SELECT/UPDATE etc. Datenbankprogrammierung 4
I Hibernate / JPA - Spaltenname von Query (Select) bekommen Datenbankprogrammierung 6
OnDemand Select * from bringt keine Rückgabe Datenbankprogrammierung 49
M JPA: select all mit unterschiedlichem Tablename Datenbankprogrammierung 2
A MySQL Select und Insert in Java Datenbankprogrammierung 15
J JPA: Wie sieht der select aus? Datenbankprogrammierung 2
D geänderte SELECT Abfragen Datenbankprogrammierung 15
N SQLite Hibernate und Aufruf von Funktion SELECT last_insert_rowid() Datenbankprogrammierung 2
T sqlite select Datenbankprogrammierung 12
D Oracle NullPointerException bei select mit Null Values Datenbankprogrammierung 5
F MySQL Was bedeuten die Einzelnen Zeichen in Select Querrys? Datenbankprogrammierung 1
J SQL SELECT mit einem Array Datenbankprogrammierung 1
J SELECT Abfrage/Suche Datenbankprogrammierung 4
E Kann man in einer if-Bedingung auch SELECT-Statements überprüfen? Datenbankprogrammierung 23
M SQL-Exception trotz funktionierendem SELECT Datenbankprogrammierung 4
U PostgreSQL SELECT Statement Datenbankprogrammierung 5
L Select Anweisung wird falsch interpretiert Datenbankprogrammierung 3
C HSQLDB Platzhalter in SELECT Datenbankprogrammierung 6
I SELECT bei Datenbankverbindung Datenbankprogrammierung 6
C MySQL JPA - namedQuery (SELECT) -getResultList() - liefert falsches Ergebnis Datenbankprogrammierung 1
S select: alle ergebnisse ermitteln Datenbankprogrammierung 5
G SQLite SQLite Select für View vereinfachen/optimieren Datenbankprogrammierung 4
C SQL-Statement SELECT über 3 Tabellen Datenbankprogrammierung 5
H HSQLDB insert .... values("test1",select test2 from foo) Datenbankprogrammierung 2
D JDBC insert mit select abfrage Datenbankprogrammierung 5
W SELECT oder Programm-Logik Datenbankprogrammierung 10
J Hibernate Select auf Parameterliste Datenbankprogrammierung 3
T MySQL Dynamisch Suchen Select Datenbankprogrammierung 4
D ArrayList in Select Datenbankprogrammierung 12
N Select mit join Datenbankprogrammierung 3
F Oracle select sum() join select sum() Datenbankprogrammierung 9
B SELECT ja - INSERT nein (MySQL) Datenbankprogrammierung 3
R Oracle Performance bei SELECT mit vielen Reihen Datenbankprogrammierung 5
T MySQL Db select * und Insert schlagen fehl Datenbankprogrammierung 2
I Select-Statement optimieren Datenbankprogrammierung 14
M Variable in SQL SELECT * FROM ... WHERE mithilfe von PreparedStatement benutzen? Datenbankprogrammierung 28
R Derby/JavaDB Möglichkeit von einem Random Select! Datenbankprogrammierung 6
B Mehrfachschachtelung SELECT Datenbankprogrammierung 2
T MySQL Select: Zusammenfassen von Daten und bilden von Durchschnitt? Datenbankprogrammierung 4
GianaSisters MySQL Datenbank Select error Datenbankprogrammierung 5
R Select Statement als temporärer Table Datenbankprogrammierung 7
R Derby/JavaDB Select Statement Where bedingung will nicht ganz! Datenbankprogrammierung 4
R Derby/JavaDB Select TOP Statement geht nicht Datenbankprogrammierung 3
S MySQL Problem mit SELECT bzw encoding Datenbankprogrammierung 4
B HSQLDB Probleme mit Select...Where Abfrage Datenbankprogrammierung 16
F wie funktioniert if Statement in SELECT? Datenbankprogrammierung 2
J [Hibernate] Select Statement Datenbankprogrammierung 4
A SQLite SELECT von ungleichen Spaltenpaaren Datenbankprogrammierung 10
Eldorado MySQL SELECT mit GROUP BY und INNER JOIN Datenbankprogrammierung 2
M Hibernate JPQL SELECT optional? Datenbankprogrammierung 2
C Datenbank-Abfrage, if im Select Datenbankprogrammierung 9
G Aufruf von SELECT INTO Datenbankprogrammierung 8
B H2 PreparedStatement SELECT * FROM ? Datenbankprogrammierung 4
X Select Query auf Substring Datenbankprogrammierung 2
S Select eines bestimmten Datensatzes Datenbankprogrammierung 4
M Select * from mydaten where ... Datenbankprogrammierung 4
T Unerwartete Datenbankausgabe bei "select now()" (es wird ein .0 angehängt) Datenbankprogrammierung 5
M Probleme bei Select in Schleife Datenbankprogrammierung 7
G SELECT liefert leere Zeilen Datenbankprogrammierung 32
M SELECT longtext -> als String behandeln Datenbankprogrammierung 6
H Select in einem Select Datenbankprogrammierung 7
G Select- Abfrage Datenbankprogrammierung 19
S Insert mit Select Datenbankprogrammierung 6
G MSSQL Server SELECT Abfrage funktioniert nicht Datenbankprogrammierung 4
R SELECT aus hsqldb mit Parameter Datenbankprogrammierung 2
H Beim insert bekomme ich den Fehler missing select keyword Datenbankprogrammierung 2
A Problem mit einem Select-Befehl Datenbankprogrammierung 5
E Neues select auf ein vorhandenes Resultset Datenbankprogrammierung 11
A SELECT-Anweisung liefert keine Datensätze zurück Datenbankprogrammierung 9
S Select über mehrere Datenbanksysteme Datenbankprogrammierung 14
P SELECT Datenbankprogrammierung 20
T select Abfrage in Java Integer speichern ? Datenbankprogrammierung 2
B fehler bei select befehl Datenbankprogrammierung 5
S Select von bis in DB2 Datenbankprogrammierung 8
S Select mit PreparedStatement Datenbankprogrammierung 2
E Ein If und ein SELECT in Oracle? Datenbankprogrammierung 2
T Select Statement auf Relation Datenbankprogrammierung 3
4 Probleme mit Select abfrage Datenbankprogrammierung 4
G Fehler in der select-Abfrage Datenbankprogrammierung 3
N SELECT: Datensatz sperren Datenbankprogrammierung 6
isowiz SELECT SUM() Ergebnis in Java abfragen Datenbankprogrammierung 6
T LIMIT In SELECT Anweisung Datenbankprogrammierung 4
R Select und Insert in Schleife - Problem mit ResultSet Datenbankprogrammierung 2
G SELECT Name= " " verhindern Datenbankprogrammierung 5
G Syntax für Select - Abfrage mit Variablen Datenbankprogrammierung 39
J SELECT-Statement Datenbankprogrammierung 4
R Select auf der Konsole ausgeben Datenbankprogrammierung 2
D brauche mal kurz hilfe bei einem select-stmt Datenbankprogrammierung 6
G Select-Abfragen sind sehr langsam Datenbankprogrammierung 7
D HSQLSB SELECT Datenbankprogrammierung 9
T compiler fehler: should be mapped with insert="false" update="false" Datenbankprogrammierung 1
bueseb84 Spring Boot : Update Mysql Datenbank Datenbankprogrammierung 1
OnDemand Mysql UPDATE if condition Datenbankprogrammierung 14
OnDemand MySQL Trigger löst nicht aus bei Hibernate Update Datenbankprogrammierung 12
R HSQLDB ResultSet update aktualisiert DB, aber nicht das ResultSet Datenbankprogrammierung 2
F UPDATE - Befehl nur in einer Zeile Datenbankprogrammierung 11
L SQL-Statement INSERT INTO ON DUPLICATE KEY UPDATE funktioniert nicht Datenbankprogrammierung 5
M SQL-Statement SQL mit Java, Update Fehler Datenbankprogrammierung 1
OnDemand Update auf Mysql läuft nicht durch Datenbankprogrammierung 30
OnDemand SQL-Statement Update mit innerjoin Datenbankprogrammierung 18

Ähnliche Java Themen

Neue Themen


Oben