背景
通常我们在做数据分析与处理之前,需要把从网站爬取的数据或者从 甲方 系统中导出的数据存入到自己的数据库中。如果数据量小,直接利用 SQL的 Insert 语句逐条插入就好。可是数据量上万条之后,再利用这样的方法就会奇慢无比,让人无法忍受。
最近在优化 台区线损排查分析软件 时遇到从集中器采集的上万条语句的入库,以及 继电保护可靠性评估与检修决策软件 中导入几万条 变电站一次设备的保护告警数据,都需要等待很长时间的问题。虽然解决问题时,是难过的,但搞定之后还是非常的开心。很享受这样的心流体验。
现在,我把解决的方法记录下来,以方便大家在遇到此类问题时作为参考。
技术分析
最开始,使用 OleDb,打开数据库链接以后,先生成几万条 SQL 的insert
语句,然后循环遍历执行,向数据库中写入记录,慢的出翔了。
不能忍,尝试改进一个版本。
仍然使用 OleDb,采用参数赋值的方法,构造 OleDbParameter,然后循环修改参数,向数据库中写入记录,结果没有性能提升。
不能忍,继续尝试其它的方法。
这次使用 Transaction,通过事务的方式向数据库中写入记录,由于事务将大量的 SQL 语句一次提交处理,所以速度有所提升,但仍然慢的要死。
不能忍,继续尝试改进,要哭死的感觉。
查了很多资料,这次使用 OleDbDataAdapter,利用这个桥接器将插入的数据更改(Update)回数据源,可依然慢的要死。
没有办法,问题需要解决,继续寻找解决方案。
受到这个帖子的启发,这次使用 DAO 的方式。
结果喜人,把以前5分钟左右的插入问题,3秒钟之内完成,提升10多倍。
论坛帖子代码实现
1.利用 OleDbDataAdapter 方式。
public void InsertRow(DataTable dataTable)
{
if (IsConnected == false)
throw new Exception("没有与数据库进行连接.");
if (dataTable == null)
throw new ArgumentNullException();
if (string.IsNullOrEmpty(dataTable.TableName))
throw new Exception("DataTable 的 TableName属性需要赋值。");
List<string> columnList = new List<string>();
foreach (DataColumn one in dataTable.Columns)
{
columnList.Add(one.ColumnName);
}
string tableName = dataTable.TableName;
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.SelectCommand = new OleDbCommand("select * from " + tableName, _pOleDbConnection);
using (OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter))
{
adapter.InsertCommand = builder.GetInsertCommand();
foreach (string one in columnList)
{
adapter.InsertCommand.Parameters.Add(one, dataTable.Columns[one].DataType);
}
adapter.Update(dataTable);
}
}
2. 利用 DAO 方式。
using Microsoft.Office.Interop.Access.Dao;
public override void InsertRow(DataTable dataTable)
{
if (dataTable == null)
throw new ArgumentNullException();
if (string.IsNullOrEmpty(dataTable.TableName))
throw new Exception("DataTable 的 TableName属性需要赋值。");
List<string> columnList = new List<string>();
foreach (DataColumn one in dataTable.Columns)
{
columnList.Add(one.ColumnName);
}
string fileName = _pConnectionProperty.ParentDirectory + "\\" + _pConnectionProperty.Name;
DBEngine dbEngine = new DBEngineClass();
Database db = dbEngine.OpenDatabase(fileName);
Recordset rs = db.OpenRecordset(dataTable.TableName);
Field[] myFields = new Field[columnList.Count];
for (int i = 0, len = myFields.Length; i < len; i++)
{
myFields[i] = rs.Fields[columnList[i]];
}
for (int i = 0, len = dataTable.Rows.Count; i < len; i++)
{
rs.AddNew();
for (int j = 0;j < myFields.Length; j++)
{
myFields[j].Value = dataTable.Rows[i][j];
}
rs.Update();
}
rs.Close();
db.Close();
}
3. 实验结果。
从Excel中导入的告警数据:
保护数据总结
到此为止,利用 C# 向 Access 数据库插入大量数据的方法就介绍完了。希望对大家有用。其实,我们学技能就应该以问题为导向,这些东西在数据库原理的书中是不会涉及的,只有不断的去搜索,去尝试才能把知识内化,为自己所用!好了,就到这里吧!See You!
相关图文:
- 如何利用 C# 实现 K 最邻近算法?
- 如何利用 C# 实现 K-D Tree 结构?
- 如何利用 C# + KDTree 实现 K 最邻近算法?
- 如何利用 C# 对神经网络模型进行抽象?
- 如何利用 C# 实现神经网络的感知器模型?
- 如何利用 C# 实现 Delta 学习规则?
- 如何利用 C# 开发「桌面版百度翻译」软件!
- 如何利用 C# 开发「股票数据分析软件」(上)
- 如何利用 C# 开发「股票数据分析软件」(中)
- 如何利用 C# 开发「股票数据分析软件」(下)
- 如何利用 C# 爬取「财报说」中的股票数据?
- 如何利用 C# 爬取 One 持有者返利数据!
- 如何利用 C# 爬取Gate.io交易所的公告!
- 如何利用 C# 爬取BigOne交易所的公告!
- 如何利用 C# 爬取 ONE 的交易数据?
- 如何利用 C# 爬取「京东 - 计算机与互联网图书销量榜」!
- 如何利用 C# 爬取「当当 - 计算机与互联网图书销量榜」!
- 如何利用 C# 爬取「互动出版网 - 计算机图书销量榜」!
- 如何利用 C# 爬取「中国图书网 - 计算机与互联网图书销量榜」!
- 如何利用 C# 爬取「猫眼电影:热映口碑榜」及对应影片信息!
- 如何利用 C# 爬取「猫眼电影专业版:票房」数据!
- 如何利用 C# 爬取「猫眼电影:最受期待榜」及对应影片信息!
- 如何利用 C# 爬取「猫眼电影:国内票房榜」及对应影片信息!
- 如何利用 C# + Python 破解猫眼电影的反爬虫机制?
- 如何利用 C# 爬取带 Token 验证的网站数据?
网友评论