Я пытаюсь выполнить запрос Linq to Entity
на EF Core 3.1.1
, и это 3X slower
, чем выполнение того же запроса на Linqpad с использованием Linq to SQL
провайдера.
var startDateTime = new DateTime(2020, 01, 18, 0, 0, 0);
var endDateTime = new DateTime(2020, 02, 26, 0, 0, 0);
var logs = _db.Logs
.Where(w => w.UserId == 10 && w.DateStamp >= startDateTime && w.DateStamp <= endDateTime)
.GroupBy(g => new
{
g.DateStamp.Date,
g.Result
}).Select(s => new
{
s.Key.Date,
s.Key.Result,
Conversions = s.Count(),
Cost = s.Sum(sum => sum.ConversionCost)
}).ToList();
Я проверил SQL, которые генерируют оба провайдера, и я бы сказал, что Linq to Entity лучше справляется с написанием запросов.
Linq to Entity
-- Region Parameters
-- @__startDateTime_0='2020-01-01T00:00:00', @__endDateTime_1='2020-02-26T00:00:00'
-- EndRegion
SELECT CONVERT(date, [l].[DateStamp]) AS [Date], [l].[Result], COUNT(*) AS [Conversions], SUM([l].[ConversionCost]) AS [Cost]
FROM [Log] AS [l]
WHERE (([l].[UserId] = 10) AND ([l].[DateStamp] >= @__startDateTime_0)) AND ([l].[DateStamp] <= @__endDateTime_1)
GROUP BY CONVERT(date, [l].[DateStamp]), [l].[Result]
Linq To SQL
-- Region Parameters
DECLARE @p0 Int = 10
DECLARE @p1 DateTime = '2020-01-01 00:00:00.000'
DECLARE @p2 DateTime = '2020-02-26 00:00:00.000'
-- EndRegion
SELECT COUNT(*) AS [Conversions], SUM([t1].[ConversionCost]) AS [Cost], [t1].[value] AS [Date], [t1].[Result]
FROM (
SELECT CONVERT(DATE, [t0].[DateStamp]) AS [value], [t0].[Result], [t0].[UserId], [t0].[DateStamp], [t0].[ConversionCost]
FROM [Log] AS [t0]
) AS [t1]
WHERE ([t1].[UserId] = @p0) AND ([t1].[DateStamp] >= @p1) AND ([t1].[DateStamp] <= @p2)
GROUP BY [t1].[value], [t1].[Result]
Pure SQL, который я написал сам.
SELECT
CONVERT(DATE, log.DateStamp),
log.Result,
Count(*),
Sum(log.ConversionCost)
FROM
log
Where UserId= 10 AND DateStamp >= '2020-01-01' AND DateStamp <= '2020-02-26'
GROUP BY
log.Result,
CONVERT(DATE, log.DateStamp)
Так что, как вы можете обнаружить, Pure SQL и Linq to Entity очень похожи на SQL, а Linq для SQL производит немного другую версию SQL. К сожалению, выполнение запроса Linq to Entity происходит примерно в 3 раза медленнее, чем два других.
Строка подключения My EF Core
data source=xxx.xxx.xxx.xxx;initial catalog=x-test;user id=x-v2;password=x72-;connection timeout=600
В чем причина?
PS , Я попытался выполнить SQL, используя Database.ExecuteSqlInterpolated, и он дал идеальную производительность, аналогичную Linq для SQL, но почему Linq to Entity не работает?