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

Don't simplify filter with custom functions over projection #800

Merged
merged 11 commits into from
Jun 26, 2019

Conversation

kosinsky
Copy link
Contributor

@kosinsky kosinsky commented Apr 26, 2019

Don't simplify filter with custom functions over projection to avoid suboptimal SQL plans and allow window functions (these function not allowed in WHERE clause)

The change helps following cases:

  • Suboptimal SQL performance with custom functions

For IQueryable that looks like:

context.Items.Select(i => new {i.Id, i.Title, Result = MyFuncs.MyFunc(i.Title)})
                      .Where(i => i.Result > 10)

EF6 simplifies expression and keeps only one SELECT with call to the function in SELECT and WHERE parts:

SELECT
       Id,
       Title,
       dbo.UDF_Test(Title) as L
FROM Items
WHERE dbo.UDF_Test(Title) > 10

Not simplified version should look like:

SELECT *
FROM (
     SELECT
           Id,
           Title,
           dbo.UDF_Test(Title) as L
     FROM Items
) T
WHERE L > 10

For table with 100K records.
Simplified query execution takes: 1100 ms of SQL CPU time
Not simplified: 600 ms of SQL CPU time

If I replace dbo.UDF_Test by LEN (build in function), execution plans are the same and no performance difference are observed.

Custom UDF are block box and database have to call function twice for each row and couldn't optimize it.

  • Window functions
    When instead of Custom UDF, window functions are used (ROW_NUMBER, LEAD, LAG, PERCENTILE_CONT etc.), SQL SERVER (and I assume every DB that supports window functions) will return error that window function supported only in SELECT or ORDER BY clauses

…suboptimal SQL plans and allow window functions (these function not allowed in WHERE clause)
@dnfclas
Copy link

dnfclas commented Apr 26, 2019

CLA assistant check
All CLA requirements met.

@kosinsky kosinsky marked this pull request as ready for review April 26, 2019 20:25
@ajcvickers ajcvickers self-assigned this Jun 25, 2019
@ajcvickers ajcvickers merged commit f656d51 into dotnet:master Jun 26, 2019
@ajcvickers
Copy link
Member

Thanks @kosinsky. Sorry for the long delay.

@divega
Copy link
Contributor

divega commented Jun 26, 2019

+1 thanks for this @kosinsky!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants