MySQL PreparedStatement vs. StoredProcedure vs. executeBatch

  • Themenstarter Themenstarter Gelöschtes Mitglied 46222
  • Beginndatum Beginndatum
G

Gelöschtes Mitglied 46222

Gast
Hallo zusammen!

Ich habe eine grundlegende Frage bezüglich Speichern in einer MySQL DB

Nehmen wir diese Klasse:
Java:
public class DummyObj 
{
public int intvalue;
public String stringvalue;

public DummyObj()
{
	intvalue=123456;
	stringvalue="awdawd";
}
}

und füllen eine Liste mit Objekten der Klasse
Java:
int i;
dummyliste = new ArrayList<DummyObj>();
for (i=0; i<100000; i++)
{
	DummyObj dummy = new DummyObj();
	dummyliste.add(dummy);
}

Nun möchte ich diese Liste in diese MysqlTabelle speichern:
SQL:
CREATE TABLE `testtable` (
  `idtesttable` int(11) NOT NULL AUTO_INCREMENT,
  `stringvalue` varchar(45) DEFAULT NULL,
  `intvalue` int(11) DEFAULT NULL,
  PRIMARY KEY (`idtesttable`)
)

Folgende Möglichkeiten ergeben sich mir:

Methode 1 - mit Stored Procedure:
ich habe diese StoredProcedure auf meinem MySQLServer
SQL:
PROCEDURE `inserttest`(
	IN v_teststring VARCHAR(45),
	IN v_testint INT
)
BEGIN
INSERT INTO testtable
SET stringvalue=v_teststring, intvalue=v_testint;
END
und rufe sie in meinem JavaCode auf
[Java]
Connection con = DriverManager.getConnection(connectionString);
int j;
CallableStatement cstmt = con.prepareCall("call inserttest(?, ?)");
for (j=0; j<dummyliste.size();j++)
{
cstmt.setString(1, dummyliste.get(j).stringvalue);
cstmt.setInt(2, dummyliste.get(j).intvalue);
cstmt.execute();
}
[/code]

Methode 2 - Prepared Statement
Java:
Connection con = DriverManager.getConnection(connectionString);
int j;
PreparedStatement pstmt = con.prepareStatement("INSERT INTO testtable SET stringvalue=?, intvalue=?;");
for (j=0; j<dummyliste.size();j++)
{				
	pstmt.setString(1, dummyliste.get(j).stringvalue);
	pstmt.setInt(2, dummyliste.get(j).intvalue);
	pstmt.executeUpdate();
}

Methode 3 - Statement mit Batch
Java:
Connection con = DriverManager.getConnection(connectionString);
int j;
Statement stmt = con.createStatement();
for (j=0; j<dummyliste.size();j++)
{
	stmt.addBatch("INSERT INTO testtable SET stringvalue=\""+dummyliste.get(j).stringvalue+"\", intvalue="+dummyliste.get(j).intvalue+";");
}
stmt.executeBatch();

Ich habe es gerade seperat mit allein 3 Methode getestet und konnte keine bedeutsamen Geschwindigkeitsunterschiede festestellen, Methode 2 und 3 waren sogar identisch
Gibt es sonstige Gründe, warum man die eine Methode der anderen vorziehen sollte oder eben nicht?

Grüße
Stefan

Edit: Fehler / Formatierung korrigiert
 
Zuletzt bearbeitet von einem Moderator:
Mit StoredProcedures bist du in der Lage deine Abfrage hochgradig auf die von dir genutzte Datenbank zu optimieren und (sofern alles richtig gemacht wird) auch die bestmögliche Performance herauszukitzeln. Der Große Nachteil ist jedoch, dass deine SPs in der Regel nicht portabel sind. Wenn du andere Datenbanken nutzen willst, musst du im schlimmsten Fall alles neu machen.

PreparedStatement werden für dich automatisch seitens des Anbieters des Treibers bereits mehr oder weniger gut optimiert. Bei einer einzigen Abfrage hinkt die Performance vermutlich der einer "normalen" Abfrage deutlich hinterher. Wenn du hingegen sehr viele Abfrage während der selben bestehenden Datenbankverbindung abschickst, dann solltest du hier einen deutlichen Performancegewinn feststellen.

Normale Statements sind im Vergleich zu PreparedStatements sehr anfällig für SQL-injections. Ich würde sie nur einsetzen, wenn der Anwender keinen Einfluss auf die Abfrage hat und es tatsächlich auf Performance bei einzelnen Abfragen ankommt.
 

Neue Themen


Zurück
Oben