# ODBC-Treiber sehr langsam



## Rin (11. Mai 2011)

Hallo leute,

ich habe ein problem mit ODBC-Treibern also folgende Rutine:

```
public static void ImportFromCsvToAccessTable (String accessTableName
			, String csvDirPath, String csvFileName) throws ClassNotFoundException, SQLException {
			frm_start start = new frm_start();
			Connection con = DriverManager.getConnection("jdbc:odbc:mydb");

			try{
				Date nowDate = new Date();
				SimpleDateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm");
				String now = df.format(nowDate);
				CsvReader reader = new CsvReader(csvDirPath +  "\\" +  csvFileName);
				reader.setDelimiter(';');
				reader.readHeaders();
				ArrayList<String> dlist = new ArrayList<String>();


				while (reader.readRecord())
				{
					String[] values = reader.getValues();
					StringBuffer strgSQLbuff = new StringBuffer();

					strgSQLbuff.append("INSERT INTO Import2(SDCallID,Eroeffnet,Beschreibung,Einmelder," +
							"EinmelderEmail,Betroffener,BetroffenerEmail,LastImport) ");
							strgSQLbuff.append("VALUES(");

						for (int i = 0; i < values.length - 1; i++)
						{
							String newValue = values[i].replaceAll("\'", "\"");
							strgSQLbuff.append("'" + newValue + "'");
							if (i < values.length - 1)
							strgSQLbuff.append(",");
						}

					strgSQLbuff.append("'" + now+ "'");
					strgSQLbuff.append(");");
					dlist.add(strgSQLbuff.toString());
				}

				Iterator<String> it = dlist.iterator();

					try
					{
						while(it.hasNext())
						{
							String strgSQL = (String) it.next();
							System.out.println(strgSQL);
							PreparedStatement selectPrepSt = con.prepareStatement(strgSQL);
							boolean result = selectPrepSt.execute();
							System.out.println("result = " + result + "Import Tabelle gefüllt!" );
						}
					}
					catch (SQLException e)
					{
						JOptionPane.showMessageDialog(start, "Es ist ein Fehler beim importieren der Daten aufgetreten! " +
													 "Die csv-Datei ist fehlerhaft!",
													 "Fehler!", JOptionPane.ERROR_MESSAGE);
						System.out.println("Fehler bei Import: ");
						e.printStackTrace();
					}

				boolean result;

					try
					{
						String copyStmt1 = "INSERT INTO Einmelder2(Einmelder,EinmelderEmail) " +
								"SELECT DISTINCT import.Betroffener, import.BetroffenerEmail " +
								"FROM Import2 import " +
								"WHERE import.Betroffener <> '' " +
								"AND import.Betroffener IS NOT NULL " +
								"AND NOT EXISTS " +
								"(SELECT * FROM Einmelder2 einm2 WHERE einm2.Einmelder = import.Betroffener);";
								PreparedStatement copyPrepSt1 = con.prepareStatement(copyStmt1);
								result = copyPrepSt1.execute();
					}
					catch (SQLException e)
					{
						JOptionPane.showMessageDialog(start, "Beim einlesen der Einmelder/Betroffenen ist ein Fehler aufgetreten!" +
													 "Einmelder ist schon vorhanden!",
													 "Fehler!", JOptionPane.ERROR_MESSAGE);
						e.printStackTrace();
					}

					try
					{
					String copyStmt2 = "INSERT INTO Einmelder2(Einmelder,EinmelderEmail) " +
								"SELECT DISTINCT import.Einmelder, import.EinmelderEmail FROM Import2 import " +
								"WHERE (import.Betroffener = '' OR import.Betroffener IS NULL) " +
								"AND NOT EXISTS " +
								"(SELECT * FROM Einmelder2 einm2 WHERE einm2.Einmelder = import.Einmelder);";
						PreparedStatement copyPrepSt2 = con.prepareStatement(copyStmt2);
						result = copyPrepSt2.execute();

					}
					catch (SQLException e)
					{
						JOptionPane.showMessageDialog(start, "Beim einlesen der Einmelder/Betroffenen ist ein Fehler aufgetreten!",
								 					 "Fehler!", JOptionPane.ERROR_MESSAGE);
						e.printStackTrace();
					}

					try
					{
						String copyStmt3 = "INSERT INTO Incidents2(SDCallID,Eroeffnet,Beschreibung,EinmelderID) " +
								"SELECT import.SDCallID, import.Eroeffnet, import.Beschreibung, einmelder.EinmelderID " +
								"FROM Import2 import, Einmelder2 einmelder " +
								"WHERE ((import.Betroffener IS NOT NULL AND import.Betroffener <> '') " +
								"AND import.Betroffener = einmelder.Einmelder) " +
								"OR ((import.Betroffener IS NULL OR import.Betroffener = '') " +
								"AND import.Einmelder = einmelder.Einmelder);";
						PreparedStatement copyPrepSt3 = con.prepareStatement(copyStmt3);
						result = copyPrepSt3.execute();
					}
					catch (SQLException e)
					{
						JOptionPane.showMessageDialog(start, "Beim einlesen der Tickets ist ein Fehler aufgetreten!",
													 "Fehler!", JOptionPane.ERROR_MESSAGE);
						e.printStackTrace();
					}

				String delStmt = "DELETE * FROM Import2";
				PreparedStatement deletePrepSt = con.prepareStatement(delStmt);
				result = deletePrepSt.execute();
				System.out.println(result);

				JOptionPane.showMessageDialog(start, "Import wurde durchgeführt!");

			} catch(Exception e) {
				System.out.println(e);
				e.printStackTrace();

			} finally {
				con.close();

			}

	}
```

bitte nicht wundern warum ich Preparedstatements verwende ich bin noch nicht dazu gekommen es auf statements umzuschreiben bzw. Preparedstatments vor zu bereiten, 

also folgendes problem die methode is einbandfrei gelaufen mit knapp 100 - 200 datensätzen von einem csv file in eine Access Datenbank zu importieren, jetzt habe ich den ersten Test gemacht mit einem csv file das zirka 1500-2000 datensätze enthält und sobald ich diese importieren will fängt er schnell an und ab dem hundertsten Datensatz fängt er an alle extrem lang einzeln einzulesen.... das soll aber nicht sein. jetzt habe ich gegoogelt und hab gelesen das ODBC da prinzipiel probleme macht aber leider keine lösung gefunden wie ich das beheben bzw umändern oder schneller machen kann.

ich hab mich auch nach einem alternativ driver umgesehen aber bis jetzt nur kostenpflichtige  gefunden...... 

hoffe ihr könnt mir weiter helfen

LG Rin


----------



## maki (11. Mai 2011)

PreparedStatements sind Statements eigetnlich immer zu bevorzugen.
Schätze dein Performance Problem liegt wirklich an der JDBC-ODBC Krücke, war ja nie für den Prod. Einsatz gedacht, sondern nur als Demo als es noch keine JDBC Treiber gab.
Access selber könte auch die Performace Probleme verursachen, kannst du denn keine richtige DB nehmen?


----------



## Rin (11. Mai 2011)

hm.. ja hab ich mir auch schon gedacht das access das extrem bremst 

hm... das problem ist das soll ein programm sein das einfach nur auf einen rechner läuft und von einem benutzer gesteuert wird und auch nur von einer person die daten eingesehen werden können und da is es etwas unnötig einen MySQL server oder ORACEL zu verwenden und andere opensource dbs wie SQLlite oder die Java DB hab ich bis jetzt noch nie benutzt....


lg


----------



## maki (11. Mai 2011)

Derby/JavaDB, H2, HSQL, etc. pp. sind alle gut & schnell.
Solltest mal im Forum suchen, haben ca. alle 2 Wochen einen Thread mit dem Titel "Welche Datenbank", da geht es um genau diese Datenbanken (bitte keinen neuen Thread zu diesem Thema aufmachen ).

Access ist jedenfalls die schlechteste Möglichkeit wenn es keinen Zwang gibt es zu verwenden.


----------



## Rin (11. Mai 2011)

ok werd ich mich mal umschauen =) danke für die infos in hab mir eh gerade JavaDB runtergeladen 

eine frage noch viel umschreiben brauch ich eingentlich nicht das is eh auch auf SQL Basis und halt die connection is anders gelöst und ich muss die tabellen voher per code createn oder??


----------



## maki (11. Mai 2011)

Tabellen musst du anlegen, ist bei jedem RDBMS so, JDBC ist ein Standard, da wird nix anders gelöst bei der Connection, die URL ist natürlich anders (RDBMS spezifisch).


----------

