Я использую EF6, и я хотел бы получить записи в таблице, которые находятся в группе идентификаторов.Это лучше или нет, чем это содержит?
В моем тесте, например, я использую 4 идентификатора.
Я пробую два варианта, первый с любым.
dbContext.MyTable
.Where(x => myIDS.Any(y=> y == x.MyID));
И T-SQL, который генерирует этот LINQ exrepsion является:
SELECT
*
FROM [dbo].[MiTabla] AS [Extent1]
WHERE EXISTS (SELECT
1 AS [C1]
FROM (SELECT
[UnionAll2].[C1] AS [C1]
FROM (SELECT
[UnionAll1].[C1] AS [C1]
FROM (SELECT
cast(130 as bigint) AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable1]
UNION ALL
SELECT
cast(139 as bigint) AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable2]) AS [UnionAll1]
UNION ALL
SELECT
cast(140 as bigint) AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable3]) AS [UnionAll2]
UNION ALL
SELECT
cast(141 as bigint) AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable4]) AS [UnionAll3]
WHERE [UnionAll3].[C1] = [Extent1].[MiID]
)
Как видно, T-SQL является "где существует", которые используют много подзапросы и объединения.
Второй вариант с содержит.
dbContext.MyTable
.Where(x => myIDS.Contains(x.MiID));
И T-SQL:
SELECT
*
FROM [dbo].[MiTabla] AS [Extent1]
WHERE [Extent1].[MiID] IN (cast(130 as bigint), cast(139 as bigint), cast(140 as bigint), cast(141 as bigint))
содержит переводится в "где в", но запрос гораздо менее сложным.
Я читал, что любой из них используется быстрее, поэтому я сомневаюсь, что любой из них, хотя он сложнее на первый взгляд, быстрее или нет.
Большое спасибо.
EDIT: У меня есть тест (я не знаю, если это лучший способ проверить это).
System.Diagnostics.Stopwatch miswContains = new System.Diagnostics.Stopwatch();
miswContains.Start();
for (int i = 0; i < 100; i++)
{
IQueryable<MyTable> iq = dbContext.MyTable
.Where(x => myIDS.Contains(x.MyID));
iq.ToArrayAsync();
}
miswContains.Stop();
System.Diagnostics.Stopwatch miswAny = new System.Diagnostics.Stopwatch();
miswAny.Start();
for (int i = 0; i < 20; i++)
{
IQueryable<MyTable> iq = dbContext.Mytable
.Where(x => myIDS.Any(y => y == x.MyID));
iq.ToArrayAsync();
}
miswAny.Stop();
результат: miswAny около 850 мс, а miswContains - около 4251 мс.
Итак, второй вариант с контациями медленнее.
'Entity Framework' сгенерировал код с помощью' select * '? Являются ли идентификаторы типа длинными? Откуда вы знаете, если результат не кэширован, попытались ли вы поменять порядок запросов? – Ofiris