如何提高关于Trim()的Linq查询性能

4
我们公司的表格是用带有填充空格的字段创建的。
我没有访问/更改数据库的权限。
然而,我注意到当我使用Trim()函数创建LINQ查询时,性能会大大降低。
即使是这么简单的查询也会降低性能:
Companies
.Where(c => c.CompanyName.Equals("Apple"))
.Select(c => new {
  Tick = c.Ticker.Trim(),
  Address = c.Address.Trim()
});

有没有一种方法可以更改查询,从而不会降低性能?

或者这完全取决于我的数据库管理员吗?


我建议先尝试清理数据库。通常情况下,确保数据在进入数据库之前是干净的,对所有相关方来说都要容易得多,而且比事后处理混乱的数据要容易得多。 - p.s.w.g
你能用正确数量的空格填充“Apple”吗?它可以在不调用.Trim()的情况下工作吗?你可以使用.TrimEnd()代替吗? - Gabe
@Gabe 你说得对。Where子句在没有.Trim()调用的情况下也可以工作。但是似乎并不能提高.Select的性能。 - inquisitive_one
如果查询在没有.Trim()调用的情况下具有相同的结果和性能,那么减少了什么? - Gabe
3个回答

4

快速解决方案是在查询之前填充公司名称。例如,如果列为char(50)

var paddedName = "Apple".PadRight(50);
var result = Companies
 .Where(c => c.CompanyName.Equals(paddedName))
 .Select(c => new {
     Tick = c.Ticker.Trim(),
     Address = c.Address.Trim()
 });

然而,您应该考虑修正数据库以避免进一步的问题。

如果数据类型是NVarchar(50),而不是char(50),这个解决方案是否有效? - Ehsan
是的。只要您知道数据填充到一定长度,它就应该可以工作。 - Eren Ersönmez

0

我还没有尝试过使用"Like"语句进行第一轮筛选并将其转换为.ToList(),第二轮仅在内部执行等值检查而不调用数据库的性能。

var result = (Companies
            .Where(c => c.CompanyName.StartsWith("Apple"))
            .Select(c => new
            {
                Tick = c.Ticker.Trim(),
                Address = c.Address.Trim()
            })).ToList();

 var result1=result
            .Where(c=>c.CompanyName.Trim().Equals("Apple")) 
            .Select(c => c);

0
除了Entity Framework之外,linq-to-sql有时会在遇到无法转换为SQL的方法调用时,在底层切换到linq-to-objects。因此,如果您这样做
....
.Select(c => new {
  Tick = c.Ticker.TrimEnd().TrimStart(),
  Address = c.Address.TrimEnd().TrimStart()

你会注意到生成的 SQL 不再包含 LTRIM(RTRIM()),而只有字段名,并且修剪在客户端内存中执行。显然,某种方式下,LTRIM(RTRIM()) 会导致查询计划效率降低(令人惊讶)。

如果没有前导空格,也许只需要使用 TrimEnd() 就足够了。

此外,我完全同意 p.s.w.g. 的观点,你应该尽力清理数据库,而不是在查询中修复错误数据。如果你无法完成这项工作,请找到合适的人并向他们施加压力。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接