Verwendetes Datenbanksystem: SQL
Abend zusammen,
ich habe folgenden Code um in einer SQL Tabelle eine Datensatz (ca 50 Spalten) einzufügen bzw zur prüfen ob der Eintrag vorhanden ist und ein Update zu machen.
Nur bei 150.000 Datensätzen, dauert es eine GANZE Zeit...
Wo könnte ich das ganze optimieren?
String query = "SELECT COUNT(id) FROM data_" + idUser.ToString().Remove(0, 2) + " WHERE timeslot = @pTimeSlot AND [date] = @pDate";
SqlCommand sqlCmd = new SqlCommand(query, cnSql);
sqlCmd.Parameters.AddWithValue("@pTimeSlot", timeSlot);
sqlCmd.Parameters.AddWithValue("@pDate", date.Date);
Int32 r = Convert.ToInt32(sqlCmd.ExecuteScalar());
if (Convert.ToInt32(sqlCmd.ExecuteScalar()) == 1)
{
// UPDATE
query = "UPDATE data_" + idUser.ToString().Remove(0, 2) + " SET [" + dvd.ValueFieldID.ToString("D3") + "_value] = @pValue, [" + dvd.ValueFieldID.ToString("D3") + "_textid] = @pTextID WHERE timeslot = @pTimeSlot AND date = @pDate";
sqlCmd = new SqlCommand(query, cnSql);
sqlCmd.Parameters.AddWithValue("@pTimeSlot", timeSlot);
sqlCmd.Parameters.AddWithValue("@pDate", date.Date);
sqlCmd.Parameters.AddWithValue("@pValue", dataValue);
sqlCmd.Parameters.AddWithValue("@pTextID", dvd.TextID);
Int32 res = sqlCmd.ExecuteNonQuery();
recordsUpdate++;
}
else
{
// INSERT
query = "INSERT INTO data_" + idUser.ToString().Remove(0, 2) +" ([date], [timeslot], ["+ dvd.ValueFieldID.ToString("D3") + "_value], [" + dvd.ValueFieldID.ToString("D3") + "_textid]) VALUES (@pDate, @pTimeSlot, @pValue, @pTextID)";
sqlCmd = new SqlCommand(query, cnSql);
sqlCmd.Parameters.AddWithValue("@pTimeSlot", timeSlot);
sqlCmd.Parameters.AddWithValue("@pDate", date.Date);
sqlCmd.Parameters.AddWithValue("@pValue", dataValue);
sqlCmd.Parameters.AddWithValue("@pTextID", dvd.TextID);
Int32 res = sqlCmd.ExecuteNonQuery();
recordsImport++;
}
cnSql.Close();
Hoffe ihr habt dort einige Tipps für mich
Ein erster Ansatz wäre das ganze in einer SQL Anweisung per IF NOT EXISTS zusammen zufassen.
Damit kannst du die Prüfung zusammenlegen.
Ebenfalls macht es bei der Menge an Abfragen auch Sinn diese in eine Transaktion zu kapseln bzw. mehrere Abfragen in einer Transaktion auszuführen.
Somit müsstest du anstelle von z.B. 150.000 Abfragen entweder nur eine große oder mehrere mit N Abfragen ausführen.
Dadurch sparst du schon einmal einiges an Laufzeit zwischen DB und deiner Anwendung aus!
Nachtrag:
Beispiel für If Not Exists.
string sql = "IF NOT EXISTS(SELECT timeslot , [date] FROM data_" + idUser.ToString().Remove(0, 2) + " WHERE timeslot = @pTimeSlot AND [date] = @pDate)"
"INSERT INTO data_" + idUser.ToString().Remove(0, 2) +" ([date], [timeslot], ["+ dvd.ValueFieldID.ToString("D3") + "_value], [" + dvd.ValueFieldID.ToString("D3") + "_textid]) VALUES (@pDate, @pTimeSlot, @pValue, @pTextID)"
"UPDATE data_" + idUser.ToString().Remove(0, 2) + " SET [" + dvd.ValueFieldID.ToString("D3") + "_value] = @pValue, [" + dvd.ValueFieldID.ToString("D3") + "_textid] = @pTextID WHERE timeslot = @pTimeSlot AND date = @pDate"
Ebenfalls solltest du die ganzen String Operationen wenn möglich los werden.
Diese führen zu unnötig vielen Objekten, die dann erst mal weggeräumt werden müssen.
Nachtrag 2:
Ebenfalls solltest du auf die where Spalten (timeslot, date) einen Index setzen.
Dadurch dürfte schon einiges an Performance rausgeholt werden können.
Nachtrag 3:
Welchen Sinn haben die ganzen textid/value Spalten?
Das sieht nicht nach einer normalisierten Tabelle aus.
Vermutlich macht es mehr Sinn, dass du nur ein TextId, Value und eine extra ID Spalte hast.
Aber hier müsste man wissen, welchen Sinn die Spalten haben sollen.
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.