У меня есть таблица базы данных с 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?
Совершенно, мне не приходилось вводить данные через sql-параметры, поэтому я не заметил SqlDbType. Это сработало! Я соглашусь, как только я позволю. – KallDrexx
Пожалуйста, подтвердите, что это работает, поскольку мне любопытно. Согласно документации, AnsiString не является типом Unicode, так что либо есть ошибка, интерпретирующая значение перечисления, либо позже появляется ошибка, и мой ответ может не работать. –
Он действительно работает, он заставил мои вызовы ExecuteReader() перейти с 4500 мс до 0,03 мс (в соответствии с StopWatch.ElaspedMillisends) – KallDrexx