Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

to put Take() in the different place will get different SQL #12453

Closed
xuzhg opened this issue Jun 22, 2018 · 4 comments · Fixed by #22897
Closed

to put Take() in the different place will get different SQL #12453

xuzhg opened this issue Jun 22, 2018 · 4 comments · Fixed by #22897
Assignees
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-enhancement
Milestone

Comments

@xuzhg
Copy link

xuzhg commented Jun 22, 2018

If we put "Take()" in the different place, we will get different SQL.

Steps to reproduce

  1. Just create a basic EF Core console project,
  2. Create some POCO class and DBContext class, for example "CustomerOrderContext".
  3. Do the following query/project.
  4. Notice the different Take(1) method call.
  5. Verify the log output.

1

using (CustomerOrderContext db = new CustomerOrderContext())
{
    var aa = db.Customers.Select(e => new Customer
    {
        FirstName = e.FirstName,
        LastName = e.LastName,
        UserName = e.UserName
    })
    .Take(1)
    .Select(e => new CusomterDto { FullName = e.FirstName + " " + e.LastName });
    foreach (var a in aa)
    {
        Console.WriteLine(a.FullName);
    }
}

If output the log, I can get the following information:
image

Be noted that it retrieves the "UserName" property, however that property doesn't used in the later.

2

using (CustomerOrderContext db = new CustomerOrderContext())
{
    var aa = db.Customers.Select(e => new Customer
    {
        FirstName = e.FirstName,
        LastName = e.LastName,
        UserName = e.UserName
    })    
    .Select(e => new CusomterDto { FullName = e.FirstName + " " + e.LastName })
    .Take(1);
    foreach (var a in aa)
    {
        Console.WriteLine(a.FullName);
    }
}

If output the log, I can get:

SELECT TOP(@__p_0) ([e].[FirstName] + N' ') + [e].[LastName] AS [FullName]
      FROM [Customers] AS [e]

Be noted that "UserName" property doesn't retrieve from the DB.

So, that's by design or did I make some mistaken or missed something? Thanks.

@maumar
Copy link
Contributor

maumar commented Jun 22, 2018

This is by design, Take operator forces us to produce a subquery, which complicates the overall query. You should still get correct results for both queries, difference is that in first case the second projection is performed on the client.

In general you will get better queries if operators like Skip/Take/Distinct are used as late as possible

@maumar maumar closed this as completed Jun 22, 2018
@maumar maumar added the closed-no-further-action The issue is closed and no further action is planned. label Jun 22, 2018
@divega
Copy link
Contributor

divega commented Jun 23, 2018

@maumar maybe I am missing something but it seems reasonable to expect Take to be lifted here. I get that we don't do it, and that maybe this scenario alone doesn't justify changing that, but is there any fundamental reason we can't?

@divega
Copy link
Contributor

divega commented Jun 24, 2018

Reopening this so we can discuss it in triage.

@maumar
Copy link
Contributor

maumar commented Jul 3, 2018

We can optimize this (i.e. move Take() further if there are no filters in the query after the place where Take was originally.

This can be optimized:

var aa = db.Customers.Select(e => new Customer
    {
        FirstName = e.FirstName,
        LastName = e.LastName,
        UserName = e.UserName
    })
    .Where(e => e.UserName != "Foo")
    .Take(1)
    .Select(e => new CusomterDto { FullName = e.FirstName + " " + e.LastName });

This can't be optimized:

var aa = db.Customers.Select(e => new Customer
    {
        FirstName = e.FirstName,
        LastName = e.LastName,
        UserName = e.UserName
    })
    .Take(1)
    .Where(e => e.UserName != "Foo")
    .Select(e => new CusomterDto { FullName = e.FirstName + " " + e.LastName });

@smitpatel smitpatel added the verify-fixed This issue is likely fixed in new query pipeline. label Mar 15, 2020
@bricelam bricelam modified the milestones: Backlog, MQ Sep 11, 2020
@maumar maumar added closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. and removed verify-fixed This issue is likely fixed in new query pipeline. labels Sep 24, 2020
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 6, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 7, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
maumar added a commit that referenced this issue Oct 7, 2020
Resolves #10295
Resolves #12453
Resolves #13216
Resolves #13550
Resolves #13712
Resolves #13977
Resolves #15302
Resolves #17735
@maumar maumar closed this as completed in 2403579 Oct 7, 2020
@ajcvickers ajcvickers modified the milestones: MQ, 6.0.0 Nov 25, 2020
@ajcvickers ajcvickers modified the milestones: 6.0.0, 6.0.0-preview1 Jan 27, 2021
@ajcvickers ajcvickers modified the milestones: 6.0.0-preview1, 6.0.0 Nov 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants