【问题标题】:Varying OleDb performance?改变 OleDb 性能?
【发布时间】:2012-03-09 22:24:30
【问题描述】:

我目前正在尝试使用 OleDb/JET 将 SQL Server 数据导出到 Excel 2003 文件。我最初在控制台应用程序中对导出进行了编码,它运行得足够快。但是,在 ASP.Net 请求期间运行相同的代码大约需要三倍的时间。具体来说,它在调用 OleDbCommand.ExecuteQuery 时变慢了,这会将记录插入 Excel 文件。

两者之间的唯一区别实际上是一个在控制台应用程序中运行,另一个在 IIS 中运行。除此之外,这两个应用程序都是:

  • 在我的开发机器上运行
  • 从两个应用程序引用的共享 dll 运行与以下相同的代码
  • 使用相同的连接字符串连接到同一个数据库
  • 使用完全相同的 select 语句和完全相同的参数值
  • 在我的开发机器上的相同位置创建一个全新的文件并写入它
  • 逐字节生成相同文件

在我不知道的 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();
            }
        }
    }
}

【问题讨论】:

  • 一个疯狂的猜测 - 如果控制台应用程序只写入 Excel 文件,但 ASP.Net 以这样的模式打开它,在 Excel 内部有重新计算/刷新......
  • @deathApril:在这两种情况下,他们每次都在创建一个新文件。这些文件是相同的。我会更新我的问题以提及这一点。
  • 他们是否使用相同的 COM 方法和相同的参数来创建和写入 Excel 文件?
  • 正如我在问题中提到的,它们实际上是在运行具有相同数据的相同代码。代码位于每个项目引用的第三个 C# dll 中。
  • 感谢您的帮助,但“显然”?无需花言巧语

标签: c# asp.net excel oledb


【解决方案1】:

听起来你需要a profiler

可能值得注意的是Microsoft tell you not to use ACE in ASP .NET。也许他们知道一些没有记录的实现?

Access 数据库引擎 2010 Redistributable 不打算......(用于)由系统服务或服务器端程序使用,其中代码将在系统帐户下运行,或者将同时处理多个用户身份,或者高度可重入并期望无状态行为。示例包括在没有用户登录时从任务调度程序运行的程序,或从服务器端 Web 应用程序(如 ASP.NET)调用的程序,或在 COM+ 服务下运行的分布式组件。

但是,如果您打算继续走这条路,我建议您摆脱作为中间人的应用程序并让INSERT 直接查询源数据。 ACE 应该支持this syntax:

SELECT *
FROM ExternalTable IN '' [ODBC;Driver={SQL Server}; Server=ServerName; Database=DatabaseName; Trusted_Connection=Yes]

【讨论】:

  • 我将赏金奖励给你,因为它似乎是最有可能的罪魁祸首,尽管我无法对此进行测试。
  • @rossisdead 谢谢你,好心的先生。
【解决方案2】:

在您评论这是从 aspx 页面上的按钮处理程序调用之后,我认为额外的延迟来自会话锁定。

即使您不使用会话,会话也会锁定整个请求,直到此工作完成并且页面结束。这个锁可以延迟请求,如果你对同一个路由进行两次或三次调用,一个锁另一个,但如果你看到其他页面,会话锁会增加额外的延迟。

为了避免这个会话锁,通过设置EnableSessionState="false"在页面声明中禁用了

看看

call aspx page to return an image randomly slow

Replacing ASP.Net's session entirely

【讨论】:

  • 我明白你关于会话锁定的意思,但我不明白这与我的问题有什么关系?我不是在测量请求的时间,而是创建 Excel 文件本身所需的时间。会话,甚至是其他发出请求的人,都不应该对此有所限制,尤其是因为我是唯一一个向服务器发出请求的人,而且一次只有一个人在进行。
  • @rossisdead 设置 EnableSessionState=false,进行测试,然后我们再谈...
【解决方案3】:

猜猜这可能会清除你的想法

performance pitfalls

asp-net-slower-than-console-application

【讨论】:

    猜你喜欢
    • 2012-07-03
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 1970-01-01
    相关资源
    最近更新 更多