改变OleDb性能?
我目前正在尝试使用OleDb / JET将SQL Server数据导出到Excel 2003文件。 我最初在一个控制台应用程序中编码导出,并且它工作得足够快。 但是,在ASP.Net请求期间运行相同的代码需要大约三倍的时间。 具体来说,在调用OleDbCommand.ExecuteQuery的过程中,速度会变慢,这会将logging插入到Excel文件中。
两者之间唯一的区别在于,一个在控制台应用程序中运行,另一个在IIS中运行。 除此之外,这两个应用程序是:
- 运行在我的开发机器上
- 从两个应用程序引用的共享dll运行相同的代码
- 使用相同的连接string连接到同一个数据库
- 使用相同的确切的select语句具有相同的确切参数值
- 在我的开发机器上的相同位置创build一个全新的文件并写入它
- 生成逐字节的相同文件
在ASP.Net中使用OleDb时,有什么本质上很慢,我不知道?
更新:这是有问题的代码。 控制台应用程序和ASP.Net站点中使用的导入命令是相同的。 他们都连接到我的机器本地的数据库,并且这两个应用程序都在我的机器上运行。
public void Convert(IDbCommand importCommand, string savePath, string sheetName) { var excelConnString = new OleDbConnectionStringBuilder(); excelConnString.Provider = "Microsoft.ACE.OLEDB.12.0"; excelConnString.DataSource = savePath; excelConnString["Extended Properties"] = "Excel 8.0;HDR=Yes"; using (var dr = importCommand.ExecuteReader()) { var columnCount = dr.FieldCount; using (var oleConn = new OleDbConnection(excelConnString.ToString())) { oleConn.Open(); var headers = new string[columnCount]; var formattedHeaders = new List<string>(); var qs = new List<string>(); var insertCmd = oleConn.CreateCommand(); for (var curCol = 0; curCol < dr.FieldCount; curCol++) { var name = dr.GetName(curCol); headers[curCol] = name; formattedHeaders.Add("[" + name + "]"); qs.Add("?"); insertCmd.Parameters.Add(name, OleDbType.LongVarChar, 20000); } using (var cmd = oleConn.CreateCommand()) { cmd.CommandText = string.Format("create table {0}({1})", sheetName, string.Join(",", formattedHeaders.Select(x => x + " longtext"))); cmd.ExecuteNonQuery(); } insertCmd.CommandText = string.Format("insert into {0} ({1}) values ({2})", sheetName, string.Join(",", formattedHeaders), string.Join(",", qs)); insertCmd.Prepare(); var values = new object[columnCount]; while (dr.Read()) { dr.GetValues(values); for (var i = 0; i < columnCount; i++) { insertCmd.Parameters[headers[i]].Value = values[i]; } insertCmd.ExecuteNonQuery(); } } } }
听起来像你需要一个分析器 。
可能值得注意的是, 微软告诉你不要在ASP .NET中使用ACE 。 也许他们知道一些没有logging的实现?
Access数据库引擎2010可再发行组件不打算被系统服务或服务器端程序使用,代码将在系统帐户下运行,或将同时处理多个用户身份,或者是高度可重入的预计无国籍的行为。 例子包括当没有用户login时从任务调度程序运行的程序,或者从服务器端web应用程序(如ASP.NET)调用的程序或在COM +服务下运行的分布式组件。
但是如果你要继续下去,我会build议摆脱作为中间人的应用程序,并让INSERT
直接查询源数据。 ACE应该支持这个语法 :
SELECT * FROM ExternalTable IN '' [ODBC;Driver={SQL Server}; Server=ServerName; Database=DatabaseName; Trusted_Connection=Yes]
在你的评论,这是从aspx页面上的button处理程序调用,我认为额外的延迟来自会话locking。
即使您不使用会话,会话locking整个所有的请求,直到这项工作完成和页面结束。 这个锁可以延迟请求,如果你对相同的路由进行两个或三个呼叫,一个locking另一个,而且如果你看到其他页面,会话locking会增加额外的延迟。
为了避免在页面声明中通过设置EnableSessionState="false"
也看看
调用aspx页面随机缓慢返回图像
完全取代ASP.Net的会话
猜猜这可能会清除你的想法
性能陷阱
ASP净慢于控制台的应用程序