У меня есть ситуация, когда определенный запрос linq, который выполняется для таблицы с многомиллионными строками, занимает слишком много времени. Я проанализировал вывод запроса linq и обнаружил, что он создает параметры для предложения where с использованием неправильного типа данных. Например, одно поле было определено в базе данных как Char (12), но параметр, с которым оно сравнивалось, был объявлен как NVarChar (12). После того, как я изменил запрос на использование Char вместо NVarChar, он работал менее чем за секунду, как и должен. Есть ли способ заставить linq to sql использовать правильный тип данных, как определено в файле .dbml для этого столбца? Я дважды проверил и определил его как DbType = "Char (12)" в файле контекста данных .dbml.
Вопрос
Как заставить linq использовать sql правильный тип данных для параметров sql?
- Интересно, есть ли у вас плохой кешированный план выполнения, потому что nvarchar (12) и char (12) не должны иметь большого значения. По крайней мере, я не думаю, что должны. Jack Marchetti 05.11.2009
- После небольшого тестирования, это действительно так. Я очищал кеш запросов перед каждым запуском, и он увеличился с 4 секунд до 20 мс, просто изменив тип данных. Я даже дошел до того, что преобразовал мой вызов linq в sql в простой старый запрос sql и использовал метод .ExecuteQuery () контекста данных для его запуска, и он работает молниеносно. Это определенно проблема преобразования типа данных, из-за которой SQL игнорирует индексы в таблице. Jason 05.11.2009
Ответы
Ответ 1 · рейтинг 2 · Amy B
Вы можете получить команду и напрямую сбросить типы параметров (в вашем случае на ansi-строку).
http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.getcommand.aspx http://msdn.microsoft.com/en-us/library/system.data.dbtype.aspx
Затем вы можете вызвать ExecuteReader для этой команды, получив в результате DbDataReader. Вы можете передать этот DbDataReader методу Translate вашего контекста данных, и он даст вам IEnumerable<T>, который вы ожидаете от linq.
http://msdn.microsoft.com/en-us/library/bb534213.aspx
Проблема с производительностью вызвана тем, что параметр запроса имеет другой тип, чем индекс, выбранный оптимизатором запросов. Далее происходит преобразование всего индекса в тип параметра. Это выполняется каждый раз при отправке запроса - преобразование не откладывается для последующих запросов.
Обычно я наблюдаю такое поведение при отправке набора строк в базу данных:
//this query will get correct parameter type
db.Customers.Where(c => c.Name == "Bob")
//this query can get incorrect parameter type
List<string> names = new List<string>(){"Amy", "Bob"};
db.Customers.Where(c => names.Contains(c.Name));
Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.
Похожие материалы
- Как вы называете класс, который не имеет базового класса (игнорирующий объект) и не является подклассом?
- Почему эта реализация недействительна?
- Типы возвращаемых значений для нереализованных методов в типажах
- Безопасное преобразование между беззнаковым и подписанным int
- Как передать параметр в консольную программу c с помощью Xcode?
- Имя параметра, соответствующего шаблону