AddWithValue без DBType, вызывающий медленный запуск запросов - PullRequest
1 голос
/ 06 декабря 2008

Я использовал cmd.Parameters.AddWithValue и не определял DBType (int, varchar, ...) для выполнения запросов. После просмотра SQL Profiler кажется, что запросы, выполняемые этим методом, выполняются намного медленнее, чем при указании типа данных.

Чтобы дать вам представление о том, насколько она медленнее, вот пример. Запрос представляет собой простой поиск по одной таблице, а столбец в выражении where индексируется. При указании типа данных определенный запрос выполняется примерно на 0 мс (слишком мал для измерения сервером sql) и требует 41 чтения. Когда я удаляю DBType, это может занять около 200 мс и 10000 операций чтения для завершения запроса.

Я не уверен, что это просто неверный отчет о значениях в SQL Profiler или эти значения действительно правильные, но это воспроизводимо, так как я могу добавлять и удалять DBType, и он выдаст значения, указанные в SQL Profiler.

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

[EDIT]

После некоторого начального тестирования (запуска обоих сценариев в цикле) кажется, что значения, которые дает профилировщик, являются точными.

Так же, как добавленная информация, я использую .Net 2.0 на Windows XP Pro и SQL Server 2000 на Windows 2000 для БД.

[UPDATE]

После нескольких копаний я смог найти этот пост в блоге , который может быть связан. Кажется, что строковые значения в .Net (так как они в юникоде) автоматически создаются как параметры nvarchar. Мне придется подождать до понедельника, когда я приступлю к работе, чтобы посмотреть, смогу ли я что-то сделать для решения этой проблемы. Тем не менее мне кажется, что мне нужно будет установить тип данных, чего я и пытался избежать.

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

Ответы [ 3 ]

5 голосов
/ 06 декабря 2008

Проблема связана с тем, как SQL-сервер выполняет неявные преобразования типов. Если вы фильтруете столбец VARCHAR, используя значение NVARCHAR (т. Е. N'some text '), у SQL нет другого выбора, кроме как преобразовать столбец в NVARCHAR, поскольку NVARCHAR не может быть неявно преобразован обратно в VARCHAR.

Ваш лучший обходной путь - либо указать тип, либо изменить столбец базы данных на NVARCHAR.

2 голосов
/ 16 июня 2009

Я только что столкнулся с этой ТОЧНОЙ проблемой. У меня есть устаревшая база данных с большим количеством столбцов char. Без указания типа столбца результаты заняли пару минут на одном из моих запросов. (По умолчанию это nvarchar.) При указании типа столбца результаты заняли несколько секунд.

cmd.Parameters.AddWithValue("charcolumn", "stringvalue");
cmd.Parameters[0].SqlDbType = SqlDbType.Char;

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

[править]

На самом деле ... после прочтения этого: http://www.u2u.info/Blogs/U2U/Lists/Posts/Post.aspx?ID=11

Я решил пойти с этим решением:

cmd.Parameters.AddWithValue(colName, val);
if(val is string)
  cmd.Parameters[i].DbType = DbType.AnsiString;
0 голосов
/ 06 декабря 2008

Что такое оператор SQL, сгенерированный в обоих случаях?

Я подозреваю, что он принимает значение как varchar, если вы не указали его явно.

например. SELECT OrderId FROM Orders WHERE OrderId = 1001
против SELECT OrderId FROM Orders WHERE OrderId = '1001'

...