【问题标题】:How to Improve Linq query perfomance regarding Trim()如何提高关于 Trim() 的 Linq 查询性能
【发布时间】:2013-08-05 16:32:36
【问题描述】:

我们的公司表是使用带有填充空格的字段创建的。

我无权更改数据库。

但是,我注意到当我使用 Trim() 函数创建 LINQ 查询时,性能会下降很多。

这样简单的查询表明性能下降:

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

有没有办法改变查询以不损失性能?

或者这完全取决于我的 DBA?

【问题讨论】:

  • 我会说首先尝试清理数据库。对于所有相关方而言,在数据进入数据库之前确保数据是干净的,通常比在之后尝试处理混乱的数据要容易得多。
  • 你能在"Apple" 上填充适量的空格吗?如果没有.Trim() 电话,它可以工作吗?你能用.TrimEnd()代替吗?
  • @Gabe 你是对的。 Where 子句在没有 .Trim() 调用的情况下工作。但它似乎并没有提高 .Select 的性能。
  • 如果查询在没有.Trim()调用的情况下具有相同的结果和性能,那么下降的原因是什么?

标签: c# performance linq linq-to-sql query-performance


【解决方案1】:

快速解决方案是在将您的公司名称提供给查询之前填充您的公司名称。例如,如果列是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),此解决方案是否有效?
  • 是的。只要您知道数据被填充到一定长度,它就应该可以工作。
【解决方案2】:

如果我们使用“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);

【讨论】:

    【解决方案3】:

    除了实体框架,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.您应该不遗余力地尝试清理数据库,而不是修复查询中的错误数据。如果你不能胜任这项工作,那就找对人,然后扭动他们的胳膊。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多