EF 하위 쿼리에서 Contains LINQ 연산자를 사용하는 경우, 이제 EF Core는 EXISTS 대신 SQL IN을 사용하여 더 나은 쿼리를 생성합니다. 따라서 쿼리 속도가 크게 향상될 수 있습니다.
public class MyDbContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
public DbSet<Department> Departments { get; set; }
}
public record Employee(string Name, int DepartmentId)
{
public int Id { get; init; }
}
public record Department(string Name)
{
public int Id { get; init; }
public bool IsWfhAllowed { get; set; }
}
이제 재택 근무가 허용되는 모든 직원을 확보하고 싶다고 가정해 보겠습니다. 요구 사항에 대해 다음과 같은 LINQ 쿼리를 작성할 수 있습니다.
EF 8.0 이전 버전(예: EF 7.x)을 사용 중인 경우 EF는 다음과 같은 쿼리를 생성합니다.
SELECT [e].[Id], [e].[DepartmentId], [e].[Name]
FROM [Employees] AS [e]
WHERE EXISTS (
SELECT 1
FROM [Departments] AS [d]
WHERE [d].[IsWfhAllowed] = CAST(1 AS bit) AND [d].[Id] = [e].[DepartmentId])
여기서 하위 쿼리는 외부 [Employees] 테이블을 참조하고 있으므로 [Employees] 테이블의 각 행에 대해 하위 쿼리를 실행해야 합니다(상관관계된 하위 쿼리).
EF 8.0을 사용하면 EF는 다음 쿼리를 생성합니다.
SELECT [e].[Id], [e].[DepartmentId], [e].[Name]
FROM [Employees] AS [e]
WHERE [e].[DepartmentId] IN (
SELECT [d].[Id]
FROM [Departments] AS [d]
WHERE [d].[IsWfhAllowed] = CAST(1 AS bit))
여기서 하위 쿼리는 더 이상 외부 테이블을 참조하지 않으므로 한 번만 평가할 수 있으므로 대부분의 데이터베이스 시스템에서 성능이 크게 향상됩니다.
참고: Microsoft SQL Server에서 데이터베이스는 성능이 동일할 수 있도록 첫 번째 쿼리를 두 번째 쿼리로 최적화할 수 있습니다.