Вы правы.Одна из более медленных частей запроса к базе данных - это передача выбранных данных из СУБД в локальный процесс.Следовательно, разумно ограничить это.
Каждый TimeDomainDataPoint
имеет первичный ключ.Все RecordValues
этого TimeDomainDataPoint
имеют внешний ключ TimeDomainDataPointId
со значением, равным этому первичному ключу.
Так что если TimeDomainDataPoint с идентификатором 4 имеет тысячу RecordValues, то у каждого RecordValue будет внешний ключсо значением 4. Было бы бесполезно передавать это значение 4 1001 раз, в то время как вам нужно только один раз.
При запросе данных всегда используйте Выберите и выберитетолько те свойства, которые вы действительно планируете использовать.Используйте Включить только если вы планируете обновить извлеченные включенные элементы.
Следующее будет намного быстрее:
var result = dbContext.timeDomainDataPoints
// first limit the datapoints you want to select
.Where(datapoint => d.RecordValues.Any(rv => rv.RecordKind.RecordAlias != null))
.Where(datapoint => datapoint.Source == 235235)
.Where(datapoint => datapoint.timeData.time >= start
&& datapoint.timeData.time <= end)
.OrderByDescending(datapoint => datapoint.timeData.time)
// then select only the properties you actually plan to use
Select(dataPoint => new
{
Id = dataPoint.Id,
RecordValues = dataPoint.RecordValues
.Where(recordValues => ...) // if you don't want all RecordValues
.Select(recordValue => new
{
// again: select only the properties you actually plan to use:
Id = recordValue.Id,
// not needed, you know the value: DataPointId = recordValue.DataPointId,
RecordKinds = recordValues.RecordKinds
.Where(recordKind => ...) // if you don't want all recordKinds
.Select(recordKind => new
{
... // only the properties you really need!
})
.ToList(),
...
})
.ToList(),
TimeData = dataPoint.TimeData.Select(...),
...
});
Возможное улучшение
Деталь:
.Where(datapoint => d.RecordValues.Any(rv => rv.RecordKind.RecordAlias != null))
используется для выборки только точек данных, имеющих значения записи с ненулевым RecordAlias.Если вы все равно выбираете RecordAlias, подумайте над тем, чтобы сделать это, где после вашего выбора:
.Select(...)
.Where(dataPoint => dataPoint
.Where(dataPoint.RecordValues.RecordKind.RecordAlias != null)
.Any());
Я не совсем уверен, что это быстрее.Если ваша система управления базами данных внутренне сначала создает полную таблицу со всеми столбцами всех объединенных таблиц, а затем отбрасывает столбцы, которые не выбраны, это не будет иметь значения.Однако, если он создает таблицу только с теми столбцами, которые фактически использует, то внутренняя таблица будет меньше.Это может быть быстрее.