热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#中SQLServer与Access批量数据插入性能对比

本文探讨了使用C#在SQLServer和Access数据库中批量插入多条数据的性能差异。通过具体代码示例,详细分析了两种数据库的执行效率,并提供了优化建议。

1. Access 数据库代码实现

以下是将多条紧固结果数据保存到Access数据库的方法:

private void SaveResultToMyaccess(PMOpenProtocol.TighteningResultData data) {
try {
myAccess.AccessDbClass();
OleDbTransaction myTrans = myAccess.Conn.BeginTransaction();
OleDbCommand cmd = myAccess.Conn.CreateCommand();
cmd.Transaction = myTrans;
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.Append("INSERT INTO mydata (TighteningID, ProductSN, PsetName, StationName, BoltNumber, TighteningStatus, ResultDateTime, FinalTorque, FinalAngle, TorqueMax, TorqueMin, OperateDateTime, OperateFlag, ErrorInfo)");
sqlBuilder.Append(" VALUES (@TighteningID, @ProductSN, @PsetName, @StationName, @BoltNumber, @TighteningStatus, @ResultDateTime, @FinalTorque, @FinalAngle, @TorqueMax, @TorqueMin, @OperateDateTime, @OperateFlag, @ErrorInfo)");
for (int i = 1; i <= data.Number_of_Bolts; i++) {
using (OleDbCommand incmd = new OleDbCommand(sqlBuilder.ToString(), myAccess.Conn)) {
incmd.Parameters.AddWithValue("@TighteningID", data.TighteningID);
incmd.Parameters.AddWithValue("@ProductSN", data.IDRes);
incmd.Parameters.AddWithValue("@PsetName", data.ModeName);
incmd.Parameters.AddWithValue("@StationName", data.StationName);
incmd.Parameters.AddWithValue("@BoltNumber", type.GetField("OrdinalBoltNumber_" + i).GetValue(data));
incmd.Parameters.AddWithValue("@TighteningStatus", type.GetField("TighteningStatus_" + i).GetValue(data));
incmd.Parameters.AddWithValue("@ResultDateTime", Convert.ToDateTime(data.t_D_REAL_TIME));
incmd.Parameters.AddWithValue("@FinalTorque", Convert.ToDouble(type.GetField("FinalTorque_" + i).GetValue(data)));
incmd.Parameters.AddWithValue("@FinalAngle", Convert.ToDouble(type.GetField("FinalAngle_" + i).GetValue(data)));
incmd.Parameters.AddWithValue("@TorqueMax", Convert.ToDouble(type.GetField("TorqueMax_" + i).GetValue(data)));
incmd.Parameters.AddWithValue("@TorqueMin", Convert.ToDouble(type.GetField("TorqueMin_" + i).GetValue(data)));
incmd.Parameters.AddWithValue("@OperateDateTime", "");
incmd.Parameters.AddWithValue("@OperateFlag", 0);
incmd.Parameters.AddWithValue("@ErrorInfo", "");
incmd.ExecuteNonQuery();
}
}
myTrans.Commit();
myAccess.Close();
} catch (Exception e) {
log.Warn("写入数据库失败,请检查数据库:" + e.ToString());
myAccess.Close();
}
}

2. SQL Server 数据库代码实现

以下是将多条紧固结果数据保存到SQL Server数据库的方法:

public void SaveMultiTighteningResult(PMOpenProtocol.TighteningResultData data) {
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.Append("INSERT INTO TighteningResult (TighteningID, ProductSN, StationCode, StationName, PsetName, BoltNumber, TighteningStatus, ResultDateTime, FinalTorque, FinalAngle, TorqueMax, TorqueMin, OperateDateTime, OperateFlag, ErrorInfo)");
sqlBuilder.Append(" SELECT @TighteningID, @ProductSN, '', @StationName, @PsetName, @BoltNumber, @TighteningStatus, @ResultDateTime, @FinalTorque, @FinalAngle, @TorqueMax, @TorqueMin, '', @OperateFlag, ''");
Type type = data.GetType();
string sql = "";
for (int i = 1; i <= data.Number_of_Bolts; i++) {
if (i == 1) {
sql = string.Format(sqlBuilder.ToString(),
data.TighteningID, data.IDRes, "", data.StationName, data.ModeName,
type.GetField("OrdinalBoltNumber_1").GetValue(data), type.GetField("TighteningStatus_1").GetValue(data),
Convert.ToDateTime(data.t_D_REAL_TIME), Convert.ToDouble(type.GetField("FinalTorque_1").GetValue(data)),
Convert.ToDouble(type.GetField("FinalAngle_1").GetValue(data)), Convert.ToDouble(type.GetField("TorqueMax_1").GetValue(data)),
Convert.ToDouble(type.GetField("TorqueMin_1").GetValue(data)), "", 0, "");
} else {
sqlBuilder.Append(" UNION ALL SELECT @TighteningID, @ProductSN, '', @StationName, @PsetName, @BoltNumber, @TighteningStatus, @ResultDateTime, @FinalTorque, @FinalAngle, @TorqueMax, @TorqueMin, '', @OperateFlag, ''");
sql = string.Format(sqlBuilder.ToString(),
data.TighteningID, data.IDRes, "", data.StationName, data.ModeName,
type.GetField("OrdinalBoltNumber_" + i).GetValue(data), type.GetField("TighteningStatus_" + i).GetValue(data),
Convert.ToDateTime(data.t_D_REAL_TIME), Convert.ToDouble(type.GetField("FinalTorque_" + i).GetValue(data)),
Convert.ToDouble(type.GetField("FinalAngle_" + i).GetValue(data)), Convert.ToDouble(type.GetField("TorqueMax_" + i).GetValue(data)),
Convert.ToDouble(type.GetField("TorqueMin_" + i).GetValue(data)), "", 0, "");
}
}
try {
SQLHelper.Update(sql);
} catch (SqlException ex) {
log.Warn("数据库操作出现异常!具体信息:" + ex.Message);
} catch (Exception ex) {
log.Warn("异常!具体信息:" + ex.Message);
}
}

3. 性能对比测试

为了评估SQL Server和Access数据库的性能,我们进行了以下测试:

Stopwatch sw = new Stopwatch();
sw.Start();
SaveMultiTighteningResult(data); // 将数据保存到SQL Server数据库
sw.Stop();
Console.WriteLine("SQL Server用时:" + sw.Elapsed.TotalMilliseconds + " 毫秒");
Stopwatch sw2 = new Stopwatch();
sw2.Start();
SaveResultToMyaccess(data); // 将数据保存到Access数据库
sw2.Stop();
Console.WriteLine("Access用时:" + sw2.Elapsed.TotalMilliseconds + " 毫秒");

测试结果显示:
SQL Server用时:172.4197 毫秒
Access用时:454.1316 毫秒

为了不影响界面的卡顿,建议将数据保存操作放入线程中处理:

Stopwatch sw = new Stopwatch();
sw.Start();
Thread th2 = new Thread(() => SaveMultiTighteningResult(data)); // 将数据保存到SQL Server数据库
th2.Start();
sw.Stop();
Console.WriteLine("SQL Server用时:" + sw.Elapsed.TotalMilliseconds + " 毫秒");
Stopwatch sw2 = new Stopwatch();
sw2.Start();
Thread th = new Thread(() => SaveResultToMyaccess(data)); // 将数据保存到Access数据库
th.Start();
sw2.Stop();
Console.WriteLine("Access用时:" + sw2.Elapsed.TotalMilliseconds + " 毫秒");

推荐阅读
  • 本问题探讨了在特定条件下排列儿童队伍的方法数量。题目要求计算满足条件的队伍排列总数,并使用递推算法和大数处理技术来解决这一问题。 ... [详细]
  • 在项目部署后,Node.js 进程可能会遇到不可预见的错误并崩溃。为了及时通知开发人员进行问题排查,我们可以利用 nodemailer 插件来发送邮件提醒。本文将详细介绍如何配置和使用 nodemailer 实现这一功能。 ... [详细]
  • C#设计模式学习笔记:观察者模式解析
    本文将探讨观察者模式的基本概念、应用场景及其在C#中的实现方法。通过借鉴《Head First Design Patterns》和维基百科等资源,详细介绍该模式的工作原理,并提供具体代码示例。 ... [详细]
  • Appium + Java 自动化测试中处理页面空白区域点击问题
    在进行移动应用自动化测试时,有时会遇到某些页面没有返回按钮,只能通过点击空白区域返回的情况。本文将探讨如何在Appium + Java环境中有效解决此类问题,并提供详细的解决方案。 ... [详细]
  • 利用Selenium与ChromeDriver实现豆瓣网页全屏截图
    本文介绍了一种使用Selenium和ChromeDriver结合Python代码,轻松实现对豆瓣网站进行完整页面截图的方法。该方法不仅简单易行,而且解决了新版Selenium不再支持PhantomJS的问题。 ... [详细]
  • 通常情况下,修改my.cnf配置文件后需要重启MySQL服务才能使新参数生效。然而,通过特定命令可以在不重启服务的情况下实现配置的即时更新。本文将详细介绍如何在线调整MySQL配置,并验证其有效性。 ... [详细]
  • 本文介绍如何在 C++ 中使用链表结构存储和管理数据。通过具体示例,展示了静态链表的基本操作,包括节点的创建、链接及遍历。 ... [详细]
  • 本文旨在提供一套高效的面试方法,帮助企业在短时间内找到合适的产品经理。虽然观点较为直接,但其方法已被实践证明有效,尤其适用于初创公司和新项目的需求。 ... [详细]
  • 解决FCKeditor应用主题后上传问题及优化配置
    本文介绍了在Freetextbox收费后选择FCKeditor作为替代方案时遇到的上传问题及其解决方案。通过调整配置文件和调试工具,最终解决了上传失败的问题,并对相关配置进行了优化。 ... [详细]
  • 反向投影技术主要用于在大型输入图像中定位特定的小型模板图像。通过直方图对比,它能够识别出最匹配的区域或点,从而确定模板图像在输入图像中的位置。 ... [详细]
  • 在使用STM32Cube进行定时器配置时,有时会遇到延时不准的问题。本文探讨了可能导致延时不准确的原因,并提供了解决方法和预防措施。 ... [详细]
  • 深入理解Lucene搜索机制
    本文旨在帮助读者全面掌握Lucene搜索的编写步骤、核心API及其应用。通过详细解析Lucene的基本查询和查询解析器的使用方法,结合架构图和代码示例,带领读者深入了解Lucene搜索的工作流程。 ... [详细]
  • 本文详细探讨了JavaScript中的作用域链和闭包机制,解释了它们的工作原理及其在实际编程中的应用。通过具体的代码示例,帮助读者更好地理解和掌握这些概念。 ... [详细]
  • Python 内存管理机制详解
    本文深入探讨了Python的内存管理机制,涵盖了垃圾回收、引用计数和内存池机制。通过具体示例和专业解释,帮助读者理解Python如何高效地管理和释放内存资源。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
author-avatar
鉴湖侠ph
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有