我正在寻找是否可以采取一些措施来显着加快 ADO.net 插入,但仍然使用多个INSERT INTO table values (...)
命令进行插入。我正在将专有的、不可查询的数据库文件中的数据暂存到 SQL Server 中。我正在编写的实用程序将从脚本中使用。
我意识到为了获得最佳性能,INSERT INTO
追求的路线是错误的,但我仍然想知道是否应该尝试一些 ADO.net 或 SQL Server 方法。
我正在使用 C# 2010 连接到 SQL Server 2008。我将我的性能与使用 Microsoft 的 ODBC 3.5 驱动程序和 Native Client 10.0 将数据插入 SQL Server 的非托管代码进行比较。期望能够匹配 ODBC 的性能是否合理?
目标表没有索引或其他约束、触发器,它只是一个临时表。源数据是一堆非标准数据类型,我必须将它们按摩成字符串。
剥离到相关细节,我的代码是:
SqlCommand comm = new SqlCommand;
SqlConnection conn = new SqlConnection(connectionString);
conn.Open();
SqlTransaction insertTransaction = conn.BeginTransaction();
comm.Connection = conn;
comm.Transaction = insertTransaction;
while(buffer.ReadNext()) // fill a buffer that I use to make my query
{
// form my insert statement and assign it
// It looks like: INSERT INTO myTable VALUES (5,'2016-02-16',NULL,3)
// A good fraction of the data is numeric with decimal points. A good
// fraction is dates. The parsing and string building,
// extravagantly inefficient as it is, is not the culprit.
// The INSERT INTO does not specify the column names
comm.CommandText = myStatement;
if (comm.ExecuteNonQuery() != 1) {throw...}
}
insertTransaction.commit;
我试过指定不同的隔离级别;我无法指定.Snapshot
(不想配置目标数据库以允许它)。没有什么太大的不同。
如果我注释掉comm.ExecuteNoQuery
让它通过形成 INSERT 语句旋转,它会按照我认为的速度进行,如果它真的在做某事的话。如果我取消注释,它需要的时间大约是我认为应该花费的 8 倍。“‘八倍长’从何而来?” 你问。好吧,我用 Pervasive Data Integrator(ye olde Data Junction)做了一个类似的操作(端到端的相同操作)。从 Pervasive 崩溃时的诊断来看,我相信该程序正在使用连续INSERT INTO
语句进行插入,就像我一样。INSERT INTO
它比我的程序快大约 8 倍,如果我不执行它们 ,它只比形成我的语句要慢一点。
Pervasive Integrator 正在通过 ODBC 添加,并且 ODBC 驱动程序设置为使用 Sql Native 客户端。而且 Data Integrator 不是 .Net 软件。我实际上并没有尝试通过 ODBC,我想我现在会尝试它,但我的目标是摆脱 ODBC,因此它只是一个数据点,而不是解决方案,即使它更快。
我尝试填充数据表以进行批量插入,但填充数据集也花费了太长时间。我认为使用批量插入的一些替代方法是使其工作的最快方法,但即使我最终停止使用我的INSERT INTO
方法,我也很好奇为什么它需要这么长时间(比我认为的要长)
插入语句相当长,我的表中有大约 350 列。