CodesInChaos 55 minutes ago

What EF needs is support for using postgresql's `array_agg` when `include`ing collections.

exceptione 3 hours ago

I don't understand the argument why `AsSplitQuery` could be more performant than a single round trip involving a multi join query. People mention data duplication and increased memory usage, but I would assume that `duplication` is just a matter of an extra pointer, not a bit-for-bit duplication of every reference to a single row.

Please enlighten me.

  • fuzzy2 3 hours ago

    If you join multiple/many tables, you could end up with a large volume of data. And yes, this is bit-for-bit duplication—on the network. The query result is (typically) a single table. This table will get serialized as-is, with all duplicate data.

    • exceptione 2 hours ago

      Couldn't we make references as `byte offsets in the result set` work to handle duplication? Real memory pointers wouldn't work over the network of course, but if the database driver would return results like this, the client could easily stitch these together. My hunch is that even if we implement references on a higher level than raw byte offsets it would still be more performant than just returning R1*R2 bytes for any R1<1:N>R2.

      ---

      EDIT: According to LLM friends you could achieve before wire de-duplication by using FOR JSON AUTO in SQL Server or jsonb_agg in PostgreSQL. Not sure how much overhead that incurs though.

      • CodesInChaos 12 minutes ago

        You'd still return a multiplicative amount of rows, even if those rows contained only a reference. `array_agg` in postgres avoids this, but EF does not support using it for collection navigations.

        One could envision a "Cartesian product" operation in the wire protocol, but I'm not convinced that's a good approach.

  • fabian2k 2 hours ago

    Assume you fetch a single customer entity with their 100 order entities as includes. With single query this will join both tables and produce 100 rows that contain the order data but also each one contains the customer data redundantly. Now Imagine you had two includes there, that will multiply the number of rows again.

    AsSingleQuery is as dangerous as this makes it sound. This works surprisingly well if you know that the number of included entities is low, but only then.

    You can get much better queries here if you write a Select() and let EF Core translate that into SQL. That will probably do roughly want you are imagining here, usually with subqueries fetching the data from related entities.

    • exceptione 2 hours ago

      Databases are incredibly smart when it comes to fetching related data, a single select is indeed better than splitting queries and doing multiple roundtrips.

      The problem however is in how results are returned over the wire. Duplicating rows is needless, but seems to be still the standard.

      • moomin 12 minutes ago

        My experience suggests that they _can_ be good, but this particular pattern they can be remarkably bad at. Source: I keep having to optimise this pattern.

  • azibi 2 hours ago

    There is a name for this problem, Cartesian explosion: https://en.wikipedia.org/wiki/Cartesian_explosion

preetham_rangu 5 hours ago

The real win in EF Core 11 is pruning the reference-nav joins out of split child queries, that's been dead weight since AsSplitQuery existed.

glub103011 19 minutes ago

I wish EF Core had first-class support for raw SQL, like Dapper.

  • CodesInChaos 3 minutes ago

    It has `context.Database.SqlQuery`