【发布时间】:2016-01-18 19:02:42
【问题描述】:
我目前正在尝试将数据表批量插入到数据库中。它工作得很好而且很快。唯一的问题出现 如果数据库中已有任何行(重复键)。
为了解决这个问题,我修改了我的程序,以便我首先检查每个新条目是否已经存在于数据库中。 这是.......慢(在目前的情况下,我没有很多条目,但后来我需要检查超过 200k 的条目,并且需要检查几次)。 因此,我需要像现在一样让它更快(如果可能的话)。
数据表的结构是这样的:
DataTable transactionTable.Columns.Add("DeviceId", typeof(Int32));
transactionTable.Columns.Add("LogDate", typeof(DateTime));
transactionTable.Columns.Add("LogType", typeof(Int32));
transactionTable.Columns.Add("LogText", typeof(String));
transactionTable.PrimaryKey = new DataColumn[3] {
transactionTable.Columns[0],
transactionTable.Columns[1],
transactionTable.Columns[2]
};
到目前为止,我有以下内容:
DataTable insertTable = transactionTable.Copy();
insertTable.Clear();
using (SqlConnection sqlcon = new SqlConnection(this.GetConnString()))
{
sqlcon.Open();
foreach (var entry in transactionTable.AsEnumerable())
{
using (SqlCommand sqlCom = sqlCon.CreateCommand())
{
sqlCom.Parameters.Clear();
sqlCom.CommandText = "SELECT 1 FROM myTable WHERE"
+ " DeviceId = @DeviceId AND LogDate = @LogDate"
+ " AND LogType = @LogType"
sqlCom.Parameters.AddWithValue("@DeviceId", entry.Field<Int32>("DeviceId"));
sqlCom.Parameters.AddWithValue("@LogDate", entry.Field<DateTime>("LogDate"));
sqlCom.Parameters.AddWithValue("@LogType", entry.Field<Int32>("LogType"));
using (SqlDataREader myRead = sqlCon.ExecuteReader()
{
myRead.Read();
if (myRead.HasRows == false)
{
insertTable.Rows.Add(entry.ItemArray);
}
}
}
}
}
// And afterwards the bulkinsert which I think is out of scope for the question itself
// (I use the insertTable there)
现在我的问题是:有什么方法可以更快地做到这一点,以免出现密钥违规问题?
【问题讨论】:
-
看看
SQL Merge(msdn.microsoft.com/en-GB/library/bb510625.aspx) -
如果您的数据库在另一个系统/服务器上,那么减少迭代中对数据库的调用次数可能会帮助您提高慢速网络连接的性能,即一次性从数据库中获取相关记录并进行比较断开的数据
-
@harman 因为它的日志只有一个日期和一个类型,我不能说这个类型是在此之后出现的,......在相关数据方面没有什么可做的。因此可悲的是,在我看到的那个方向上什么都没有
-
@JamesBrierley sql 合并是什么意思? (我的问题是我有一个数据表,我通过批量复制将其放入数据库中,如果遇到重复的键,批量复制会自动失败。所以不确定 sql 合并语句在那里有什么帮助?)
-
我在想你可以使用类似于stackoverflow.com/a/9649040/5111146 的解决方案,但我自己对 sql merge 不太了解
标签: c# sql sql-server datatable sql-server-2012