Sql оператор с использованием параметров медленно, быстро без них - PullRequest
1 голос
/ 11 февраля 2009

У меня небольшие проблемы с производительностью параметризованного оператора SQL. Таблица, с которой я работаю, содержит ~ 150 000 записей, каждая из которых имеет ~ 30 столбцов.

Этот оператор выполняется за 3,5 секунды.

    Dim selectstring As String
    selectstring = "SELECT * FROM LineInfo WHERE jobNum=@jobnum and revision_number=@revnum AND lineNum=@linenum;"
    Dim selectCommand As New SqlClient.SqlCommand(selectstring, Singleton.DbConnection)
    selectCommand.Parameters.Add("@jobnum", "testing1")
    selectCommand.Parameters.Add("@revnum", "0")
    selectCommand.Parameters.Add("@linenum", 13)

    Dim da As New SqlClient.SqlDataAdapter(selectCommand)
    Dim ds As New DataSet

    Try
        da.Fill(ds)
        MsgBox("Done.")
        ds.Dispose()
    Catch ex As System.Exception
        MsgBox(ex.Message)
    End Try

    da.Dispose()

Этот оператор выбора выполняется за 0,0015 секунды.

    Dim selectstring As String
    selectstring = "SELECT * FROM LineInfo WHERE jobNum='testing1' and revision_number=0 AND lineNum=13;"

    Dim selectCommand As New SqlClient.SqlCommand(selectstring, Singleton.DbConnection)
    Dim ds As New DataTable
    Dim a As New SqlClient.SqlDataAdapter(selectCommand)

    Try
        a.Fill(ds)
        MsgBox("Done.")
        ds.Dispose()
    Catch ex As System.Exception
        MsgBox(ex.Message)
    End Try

    a.Dispose()

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

Ответы [ 9 ]

4 голосов
/ 11 февраля 2009

Запустите SQL Profiler и проверьте фактический SQL, попавший в базу данных. Возьмите оба запроса и запустите их в Query Analyzer / SQL Server Management studio с включенным параметром Показать план выполнения и найдите, на что тратится время.

Если производительность на сервере идентична, проверьте код .NET еще раз. Есть ли причина, по которой вы используете DataSet в верхнем примере и DataTable в нижнем?

3 голосов
/ 11 февраля 2009

Я бы специально посмотрел на

selectCommand.Parameters.Add("@jobnum", "testing1")

У меня был опыт, когда он конвертировал весь индекс в юникод перед выполнением поиска. Это вероятный виновник здесь. В этом случае вы хотите создать параметр и задать ему тип ansi string или аналогичный.

3 голосов
/ 11 февраля 2009

Я ожидаю, что вы быстрее выполняете запрос, потому что SQL Server ранее кэшировал ваш точный запрос. Попробуйте изменить значения и посмотрите, быстро ли он все еще работает.

2 голосов
/ 11 февраля 2009

Мне пришлось изменить параметры оператора на:

   selectCommand.Parameters.Add("@jobnum", SqlDbType.Char).Value = "testing1"
   selectCommand.Parameters.Add("@revnum", SqlDbType.Int).Value = 0
   selectCommand.Parameters.Add("@linenum", SqlDbType.Int).Value = 13

Изменение только параметра @revnum было недостаточно, мне пришлось изменить их все. В любом случае, это работает, и теперь я знаю, как с этим справиться.

Спасибо.

2 голосов
/ 11 февраля 2009

Не могу сказать наверняка (не особо разбираюсь во всех тонкостях движков SQL), но первое, что бросается в глаза, это использование строковых параметров для числовых столбцов:

selectCommand.Parameters.Add("@revnum", "0")

против

revision_number=0

Я подозреваю, что если бы вы использовали строковые, а не числовые значения во втором примере, это также замедлило бы ... Попробуйте, посмотрите, что получится.

1 голос
/ 11 февраля 2009

Удалось ли вам последовательно воспроизводить время выполнения для каждой версии? Возможно ли, что вы сначала запустили параметризованную версию, а затем, когда вы запустили динамическую версию SQL, запрос уже был кэширован?

0 голосов
/ 29 июня 2009

Я не знаю, есть ли в вашем драйвере .net нечто подобное, но в драйвере JDBC есть опция "sendStringParametersAsUnicode", см. http://msdn.microsoft.com/de-de/library/ms378988.aspx.

0 голосов
/ 11 февраля 2009

Я считаю, что сниффинг параметров применим и к этому, поскольку SQL Server кэширует план выполнения для операторов SQL так же, как и для сохраненных процедур. Вы можете попытаться очистить кэш операторов и повторно запустить оператор с теми же параметрами, где он работает, и посмотреть, не ускоряется ли он.

0 голосов
/ 11 февраля 2009

Я сомневаюсь, что это ответ, потому что я не очень хорошо знаю VB, но я вижу, что в первом фрагменте кода revnum установлен как "0", в то время как linenum установлен как 13 (без кавычек) ,

Я не достаточно хорошо знаю типизацию данных VB, чтобы быть уверенным, но может ли быть какое-то странное поведение, когда revnum представлял собой строку и должен был преобразовываться в целое число в процессе запроса SQL?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...