2013-11-10 2 views
3

У меня есть таблица базы данных с 81 миллионом записей, которые используются для привязки определенного URL-адреса с клиентом, который запросил генерировать URL-адрес. Для того, чтобы запросить URL из этой таблицы было несколько разумным, я сделал поле url varchar(500) (максимальная длина URL-адреса, которую мы видели, равна 410).Как заставить SqlCommand не кодировать параметры как unicode/nvarchar?

Когда я запускаю следующий запрос в SSMS, я получаю результаты мгновенно:

select CustomerId, UserId, Requested from LogURL where LogData = '<url>' 

Я тогда закодирован метод в C#, чтобы сделать этот запрос для меня, чтобы обработать файлы журналов:

public UrlInformation GetInfoForUrl(string url) 
    { 
     const string query = "select top 1 CustomerId, UserId, Requested from LogURL where LogData = @url"; 

     using (var command = new SqlCommand(query, _connection)) 
     { 
      command.Parameters.Add(new SqlParameter 
      { 
       DbType = DbType.AnsiString, 
       ParameterName = "url", 
       Value = url 
      }); 

      using (var reader = command.ExecuteReader()) 
      { 
       UrlInformation info = null; 

       // Sometimes there are multiple results, just take the first 
       if (reader.Read()) 
       { 
        var customerId = reader.GetInt32(0); 
        var userId = reader.GetInt32(1); 
        var date = reader.GetDateTime(2); 

        info = new UrlInformation 
        { 
         CustomerId = customerId, 
         UserId = userId, 
         RequestedDate = date 
        }; 
       } 

       return info; 
      } 
     } 

(Обратите внимание, что этот класс создает и открывает соединение sql в конструкторе и размещает его в Dispose(), поэтому повторное использование такого же соединения).

Когда этот код работает, command.ExecuteReader() занимает 3-5 секунд каждый (измеряется с помощью класса StopWatch). Открытие в SQL Profiler я вижу фактический запрос получать исполненный:

exec sp_executesql N'select top 1 CustomerId, UserId, Requested from LogURL where LogData = @url',N'@url nvarchar(346)',@url=N'<url>' 

Поскольку это преобразование URL в nvarchar это не использует мою varchar() ссылки и, кажется, делает полное сканирование таблицы.

Как я могу получить код C# для рассмотрения url как varchar вместо nvarchar?

ответ

5

Поскольку вы используете SqlParameter может также быть с помощью SqlDbType вместо DbType. Если вы это сделаете, вы можете использовать SqlDbType.VarChar вместо DbType.Ansi.

command.Parameters.Add(new SqlParameter 
{ 
    SqlDbType = SqlDbType.VarChar, 
    ParameterName = "url", 
    Value = url 
}); 

Кроме того, из MSDN, то DbType параметр DbType получает или устанавливает SqlDbType параметра путем переопределения базы DbType недвижимость.

+1

Совершенно, мне не приходилось вводить данные через sql-параметры, поэтому я не заметил SqlDbType. Это сработало! Я соглашусь, как только я позволю. – KallDrexx

+0

Пожалуйста, подтвердите, что это работает, поскольку мне любопытно. Согласно документации, AnsiString не является типом Unicode, так что либо есть ошибка, интерпретирующая значение перечисления, либо позже появляется ошибка, и мой ответ может не работать. –

+0

Он действительно работает, он заставил мои вызовы ExecuteReader() перейти с 4500 мс до 0,03 мс (в соответствии с StopWatch.ElaspedMillisends) – KallDrexx

Смежные вопросы