2009-11-09 127 views
6

我在Linq to SQL中發現了一個巨大的性能問題。Linq to SQL nvarchar問題

從表中選擇使用字符串時,傳遞給sql server的參數始終爲nvarchar,即使sql表是varchar。這導致表掃描而不是搜索,這是一個巨大的性能問題。

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

var qa = q.ToArray(); 

該參數被穿過作爲nvarchar的,從varchar被轉換在使用前爲nvarchar這導致整個索引。

如果參數是一個varchar,它是一個非常快的搜索。

有什麼辦法可以覆蓋或改變它?

謝謝 Registers Craig。

+0

你的DBML是什麼樣的? – RobS 2009-11-09 06:44:12

+0

它是一個varchar列,不是nvarchar列。 創建表測試(測試varchar(200)非空) 在測試(測試)上創建索引ixtest – Craig 2009-11-09 07:18:20

+0

數據庫查詢計劃使用CONVERT_IMPLICIT和掃描而不是查找。我認爲這是一個常見的LINQ to SQL問題。 我正在尋找一種可以正確指定參數的解決方法。 varchar(200)而不是nvarchar(4)導致轉換。 – Craig 2009-11-09 07:20:10

回答

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()); 

BTW,我看到了另一種情況下發生這種情況是在一個表格中有奇數分佈的值(例如表格的50%具有相同的值),這意味着,由於在計劃編譯時參數對於SQL Server是未知的,因此表掃描是可用的最佳計劃。如果你的分佈也不尋常,那麼上面的解決方法將不起作用,因爲掃描不會來自缺少的轉換,而是來自參數化本身。在這種情況下,我知道的唯一解決方法是使用OPTIMIZE FOR提示並手動指定SQL。

+0

+1 .. :)這是另一個msdn線程,也有一些替代解決方法: http://social.msdn.microsoft.com/Forums/en-US/linqtosql/thread/20d456f0-9174-4745-bbc5-571f68879e27 – KristoferA 2009-11-10 03:10:20

+0

謝謝。 我已經意識到這只是包含的問題。起初我認爲它更廣泛。 – Craig 2009-11-17 08:24:56