question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Don't client-side large objects [Possible 3.x regression]

See original GitHub issue

This might be a 3.x regression. The code below was developed in 2.x and I’m 90% confident that it did what I want. We recently noticed a serious perf regression and observed the (new?) behavior described here.

Take a model that maps a DB blob into a .net byte[].

class File 
{
  public int Id { get; set; }
  public string Name { get; set; }
  public byte[] Data { get; set; }  // blob in DB
}

This query attempts to fetch the size of the first 20 records:

var q = from f in db.Files select new { f.Name, Length = f.Data.Length };
q.Take(20).ToList();

The SQL looks like this:

select Name, Data
from Files
where rownum <= 20

My gripe here is that linq2db fetches all of Data and chooses to evaluate Data.Length on the client-side.

Generally speaking, I love how linq2db evaluates as much as possible client-side. It gives access to all .net features that dbs don’t have and the results are consistent with other c# code (there’s always minor discrepancies in the implementation of “similar” functions).

In this specific instance, I don’t love it as much because Data is a heavy, costly object. Just imagine each blob is on average 5Mo. That query moves 100Mo over the network!! It’s especially nasty because it still “works”. We noticed the problem after significant perf. degradation.

I would suggest that byte[].Length is special-cased to always be server-side evaluated. I.e. above query should generate:

select Name, LENGTH(Data)
from Files
where rownum <= 20

Side note: I couldn’t find a built-in Sql.Length() that takes byte[], so working around this requires a bit of knowledge (I created my own length function).

Environment details

linq2db version: 3.1.4 Database Server: Oracle 12 Database Provider: Managed Operating system: Windows .NET Framework: Core 2.1

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
jogibear9988commented, Dec 15, 2020

@MaceWindu
It’s not so easy to fix…

Adding

		{ M(() => ((byte[])null!).Length ), N(() => L<byte[],int>((byte[] obj) => Sql.Length(obj)!.Value)) },

to Expressions does not work.

I then get this Exception: (Of cause, I added the Function before to SQL Class)

image

I’ll look if i can fix 😃

1reaction
MaceWinducommented, Dec 12, 2020

I cannot find byte.Length mapping, so I’m pretty sure it is not regression. Anyway, we need to add Sql.Length function for byte[] (we have it only for Binary for some reason) and map byte[].Length/Binary.Length to it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Client side GroupBy is not supported
Before EF Core 3.0, this was done implicitly, so EF downloaded all result rows and then applied the LINQ GroupBy . However, this...
Read more >
Client Side or Server Side Calculations?
Three simple guidelines can help. First, if a calculation/algorithm is a constant of the world and unrelated to the "business" logic of the ......
Read more >
30 kNN Interview Questions for Data Scientists [2023 Edition]
kNN interview questions for freshers and mid-senior professionals. Find top 30 kNN interview questions with explanation and solution.
Read more >
Multicollinearity in Regression Analysis: Problems, ...
Multicollinearity is when independent variables in a regression model are correlated. I explore its problems, testing your model for it, and solutions.
Read more >
Testing Your App | Cypress Documentation
What to test, where the edge cases and seams are, what regressions you're likely to run into, etc. are entirely up to you,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found