Как улучшить производительность запросов Linq относительно Trim()

Таблицы нашей компании были созданы с полями с пробелами.

У меня нет доступа / разрешений для внесения изменений в БД.

Тем не менее, я заметил, что когда я создаю запросы LINQ с использованием функции Trim(), производительность значительно снижается.

Простой запрос показывает, что производительность снижается:

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

Есть ли способ изменить запрос, чтобы не было потери производительности?

Или все это зависит только от моего администратора?

3 ответа

Быстрое решение состоит в том, чтобы добавить название вашей компании, прежде чем отправлять его на запрос. Например, если столбец 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()
 });

Тем не менее, вы должны рассмотреть возможность исправления базы данных, чтобы избежать дальнейших проблем.

Помимо Entity Framework, linq-to-sql может иногда переключаться на linq-to-objects под капотом, когда сталкивается с вызовами методов, которые не могут быть преобразованы в SQL. Так что если вы делаете

....
.Select(c => new {
  Tick = c.Ticker.TrimEnd().TrimStart(),
  Address = c.Address.TrimEnd().TrimStart()

вы заметите, что сгенерированный SQL больше не содержит LTRIM(RTRIM()), но только имя поля и то, что обрезки выполняются в памяти клиента. Видимо, как-то LTRIM(RTRIM()) вызывает менее эффективный план запроса (на удивление).

Возможно только TrimEnd() Достаточно, если нет пробелов.

Кроме того, я полностью согласен с pswg, что вы должны стараться изо всех сил пытаться очистить базу данных вместо исправления неверных данных в запросах. Если вы не можете сделать эту работу, найдите подходящих людей и скрутите их руки.

Я не проверял производительность, если мы используем оператор "Мне нравится" для выполнения фильтра первого раунда и устанавливаем его.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);
Другие вопросы по тегам