Различная производительность OleDb? - PullRequest
6 голосов
/ 10 марта 2012

В настоящее время я пытаюсь использовать OleDb / JET для экспорта данных SQL Server в файл Excel 2003. Я изначально кодировал экспорт в консольном приложении, и он работал достаточно быстро. Однако выполнение одного и того же кода во время запроса ASP.Net занимает примерно в три раза больше времени. В частности, он замедляется во время вызова OleDbCommand.ExecuteQuery, который вставляет запись в файл Excel.

Единственное различие между ними заключается в том, что одно работает в консольном приложении, а другое - в IIS. Кроме этого, оба приложения:

  • работает на моей машине для разработки
  • запускает тот же код, что и ниже, из общей библиотеки DLL, на которую ссылаются оба приложения
  • подключение к той же базе данных с той же строкой подключения
  • с использованием одного и того же оператора выбора с одинаковыми точными значениями параметров
  • создание нового файла в том же месте на моей машине для разработки и запись в него
  • создание байт-байтовых идентичных файлов

Есть ли что-то медленное по своей сути при использовании OleDb в ASP.Net, о котором я не знаю?

ОБНОВЛЕНИЕ: это код вопроса. Команда import, используемая как в консольном приложении, так и на сайтах 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();
            }
        }
    }
}

Ответы [ 3 ]

3 голосов
/ 21 марта 2012

Похоже, вам нужно профилировщик .

Вероятно, стоит отметить, что Microsoft говорит вам не использовать ACE в ASP .NET . Возможно, они знают что-то о реализации, которая не документирована?

Распространяемый Access Database Engine 2010 не предназначен ... для использования системной службой или программой на стороне сервера, где код будет выполняться под системной учетной записью, или будет одновременно работать с несколькими пользователями или очень реентерируем и ожидает безгражданства. Примерами могут быть программа, запускаемая из планировщика задач, когда пользователь не вошел в систему, или программа, вызываемая из серверного веб-приложения, такого как ASP.NET, или распределенный компонент, работающий в службах COM +.

Но если вы собираетесь продолжить этот путь, я бы предложил избавиться от вашего приложения в качестве посредника и попросить INSERT напрямую запросить исходные данные. ACE должен поддерживать этот синтаксис :

SELECT *
FROM ExternalTable IN '' [ODBC;Driver={SQL Server}; Server=ServerName; Database=DatabaseName; Trusted_Connection=Yes]
0 голосов
/ 21 марта 2012
0 голосов
/ 17 марта 2012

После вашего комментария, что это вызывается из обработчика кнопки на странице aspx, я думаю, что дополнительная задержка происходит из-за блокировки сеанса.

Даже если вы не используете сеанс, сеанс блокирует весь запрос до этогоработа заканчивается, и страница заканчивается.Эта блокировка может задержать запрос, и если вы делаете два или три вызова одной и той же маршрутизации, одна блокирует другую, но также если вы видите другие страницы, блокировка сеанса добавляет дополнительную задержку.

Чтобы избежать этой блокировки сеанса, простоотключено на объявлении страницы с помощью набора EnableSessionState="false"

Также посмотрите на

вызов страницы aspx для случайного медленного возврата изображения

ЗаменаСессия ASP.Net полностью

...