Низкая производительность SqlDataReader - PullRequest
9 голосов
/ 19 марта 2009

Я выполняю запрос ~ 2 с в MSSMS (возвращает 25K строк)

Тот же запрос, используемый в .NET (sqlReader), выполняющийся за несколько минут!

Я также пытался запустить только читатель

(прокомментировал весь код в цикле while, оставив только reader.Read ()) - все равно!

Есть идеи, что случилось?


Я не администратор и не привилегирован играть с Profiler - спросит моего администратора и сообщит всем.

Тем временем я заметил существенное повышение производительности после добавления параметра " WITH RECOMPILE " в SP. Я говорю

Итак, с моей точки зрения, это похоже на план выполнения ... Что ты думаешь?

[EDIT] Также я проверил приведенный ниже запрос из QA и .NET

select @@options

Насколько я понимаю, он должен возвращать одинаковое значение для обеих сред. (Если не отличается, будут использованы ex.plans) Я прав?

[EDIT2] Я прочитал (от http://www.sqldev.net/misc/fn_setopts.htm), что ARITHABOIRT = ВКЛ в QA (в .NET он выключен)

Кто-нибудь знает, как принудительно включить ARITHABOIRT = ON для каждого подключения .NET?

Ответы [ 5 ]

5 голосов
/ 19 марта 2009

Я бы настроил трассировку в SQL Server Profiler, чтобы увидеть, какие настройки параметров SET используются соединением при подключении из кода .NET, и какие настройки используются в SSMS. Под настройками параметров SET я имею в виду

ARITHABORT
ANSI_NULLS
CONCAT_NULL_YIELDS_NULL
//etc

Посмотрите на MSDN для таблицы параметров

Я уже видел проблему, когда варианты были разными (в этом случае ARITHABORT) и разница в производительности была огромной.

4 голосов
/ 10 августа 2010

У меня была эта проблема. Отметьте параметр «арифметическое прерывание» в настройках подключения сервера БД.

1 голос
/ 19 марта 2009

Кроме того, анализатор запросов не загружает полное содержимое большого текста или больших двоичных полей. Ваш SqlDataReader может занять больше времени, поскольку он загружает все содержимое.

0 голосов
/ 19 марта 2009

Если вы выполняете ридер в цикле, где он выполняется много раз, то убедитесь, что вы используете CommandBehavior.CloseConnection

    SqlCommand cmd = new SqlCommand();
    SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)

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

Тогда, если ваш цикл достаточно быстрый (что весьма вероятно), у вас закончатся соединения. (Пул имеет максимальный лимит, который он может генерировать)

Это приведет к дополнительным задержкам и задержкам, так как код продолжает создавать дополнительные ненужные соединения (до максимума) и ожидает, пока GC "догонит" цикл, который их использует ...

0 голосов
/ 19 марта 2009

Я бы проверил, сколько времени занимает фактический поиск.

например:

  Private Sub timeCheck()
    'NOTE: Assuming you have a sqlconnection object named conn

    'Create stopwatch
    Dim sw As New System.Diagnostics.Stopwatch

    'Setup query
    Dim com As New SqlClient.SqlCommand("QUERY GOES HERE", conn)

    sw.Start()

    'Run query
    Dim dr As SqlClient.SqlDataReader = com.ExecuteReader()

    sw.Stop()

    'Check the time
    Dim sql_query_time As String = CStr((sw.ElapsedMilliseconds / 1000)) & " seconds"
  End Sub

Это позволит вам увидеть, находится ли задержка в извлечении или в исполнении читателя.

...