Linq to SQL nvarchar问题

Cra*_*aig 9 sql linq indexing nvarchar linq-to-sql

我在Linq to SQL中发现了一个巨大的性能问题.

使用字符串从表中进行选择时,传递给sql server的参数始终为nvarchar,即使sql表是varchar也是如此.这导致表扫描而不是搜索,这是一个巨大的性能问题.

var q = (
   from a in tbl
   where a.index == "TEST"
   select a)

var qa = q.ToArray();
Run Code Online (Sandbox Code Playgroud)

该参数作为nvarchar传递,这导致整个索引在使用之前从varchar转换为nvarchar.

如果参数是varchar,那么它是一个非常快速的搜索.

有没有办法覆盖或改变这个?

谢谢关心克雷格.

Jus*_*ant 8

嗯.这是LINQ-to-SQL的RTM之前版本的已知错误,但是从我在线阅读的内容来看,这是RTM中相等比较的一个固定问题(虽然对于Contains()比较仍然存在问题).

无论如何,这是MSDN论坛上的一个主题,其中包含一些详细的解决方法:http: //social.msdn.microsoft.com/Forums/en-US/linqtosql/thread/4276ecd2-31ff-4cd0-82ea-7a22ce25308b

我最喜欢的解决方法是这个:

//define a query
IQueryable<Employee> emps = from emp in dc2.Employees where emp.NationalIDNumber == "abc" select emp;

//get hold of the SQL command translation of the query...
System.Data.Common.DbCommand command = dc2.GetCommand(emps);

//change param type from "string" (nvarchar) to "ansistring" (varchar)
command.Parameters[0].DbType = DbType.AnsiString; 
command.Connection = dc2.Connection;

//run
IEnumerable<Employee> emps2 = dc2.Translate<Employee>(command.ExecuteReader());
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我看到这种情况发生的另一种情况是在一个奇怪的值分布表中(例如50%的表具有相同的值)意味着,如果SQL Server在计划编译时未知参数,则表扫描是最好的计划可用.如果您的分发也不常见,那么上面的解决方法将不起作用,因为扫描不会来自丢失的转换,而是来自参数化本身.在这种情况下,我知道的唯一解决方法是使用OPTIMIZE FOR提示并手动指定SQL.