今天意外發現,LINQ to SQL在轉譯CHAR(1)欄位比對時,可能因寫法不同而產生極無效率的SQL指令!

當資料表的欄位為CHAR(1)時,在DataContext裡產生的對應物件型別是char,而我們直覺上可能寫成CharCol == 'A'的比對條件。但今天發現一件可怕的事...

CharCol == 'A'的寫法會被轉換成極無效率的WHERE UNICODE(CharCol) = 65

對SQL查詢效能略有研究的人都知道,Func(SomeCol) = SomeValue的寫法會迫使SQL Server把每一列的資料都挖出來運算後再比對,無法善用Index做有效率的搜索。用這種寫法的好處是可以居分大小寫不同,但效能代價十分可觀。網路上找到文章做過實測,效能差了三倍! 該文建議解法是手動將資料物件的char型別改為string,不過這涉及更動自動產生的程式碼,一旦更新DBML就得重調。我則找到另一種替代解法--改用CharCol.Equals('A')!

使用LINQPad來驗證: [關於LINQPad可參考demo的介紹文]

由以上測試可知p.Enabled.Equals('Y')會被轉換成Enabled = 'Y',就不會導致前述的查詢效能問題。

【結論】

LINQ to SQL在欄位為CHAR(1)時,若要做不分大小寫的比對,請用.Equals()取代==,以免產生效能低落的T-SQL查詢語法。

【同場加映】

System.Data.Linq.SqlClient.SqlMethods.Like(p.Player, "Dark%")可以直接對映出LIKE T-SQL語法!


Comments

Be the first to post a comment

Post a comment