statamic / eloquent-driver

Provides support for storing your Statamic data in a database, rather than flat files.
https://statamic.dev/tips/storing-content-in-a-database
MIT License
104 stars 73 forks source link

Every collection is fetched regardless of what collection I query #151

Closed geertjanknapen1 closed 1 year ago

geertjanknapen1 commented 1 year ago

I have a piece of code that gets me a certain collection entry, it looks as follows:

public function getCollectionEntry(Page|string $slug, Collection|array $collection, ?Locale $locale = null): ?EloquentEntry
    {
        $locale = getLocaleEnum($locale);
        $slugValue = is_string($slug) ? $slug : $slug->value;
        $collections = is_array($collection) ? collect($collection)->pluck('value')->toArray() : [$collection->value];

        $cacheTags = $this->prepareCacheTags($collection);

        return Cache::tags($cacheTags)->remember(
            "get_collection_entry:{$locale->value}:$slugValue" . implode('-', $collections),
            config('custom.caching.ttl'),
            function () use ($slugValue, $locale, $collections) {
                /** @var EntryQueryBuilder $entryQueryBuilder */
                $entryQueryBuilder = EntryFacade::query();

                $entry = $entryQueryBuilder
                    ->whereIn('collection', $collections)
                    ->where('slug', $slugValue)
                    ->where('published', true)
                    ->first();

                // get entry in given target locale (defaults to current locale)
                return !is_null($entry) ? $entry->in($locale->value) : null;
            }
        );
    }

This piece of code is ran the moment I hit the /en/servicedesk url. $collections in this case can be either an Enum with a single value, or an array. In this example I've already made sure that it's a single string, namely dynamic_pages.

However when I check the performance for this in the Laravel debug bar, I see that there are SELECT * FROM entries WHERE collection = ... ; for almost all my collections. Furthermore there are a lot of duplicate queries that seem to try to get the origin of a specific entry (that I am not even querying).

I am going to share examples below, what I wanna know though it, why is this happening? Am I doing something wrong?

The query it does correctly;

image

The unnecessary (I think) queries;

image

A lot of duplicates;

image image

Coming from

image

ryanmitchell commented 1 year ago

There are open PRs to resolve both of these. On 10 May 2023, at 15:26, Geert-Jan Knapen @.***> wrote: I have a piece of code that gets me a certain collection entry, it looks as follows: public function getCollectionEntry(Page|string $slug, Collection|array $collection, ?Locale $locale = null): ?EloquentEntry { $locale = getLocaleEnum($locale); $slugValue = is_string($slug) ? $slug : $slug->value; $collections = is_array($collection) ? collect($collection)->pluck('value')->toArray() : [$collection->value];

    $cacheTags = $this->prepareCacheTags($collection);

    return Cache::tags($cacheTags)->remember(
        "get_collection_entry:{$locale->value}:$slugValue" . implode('-', $collections),
        config('custom.caching.ttl'),
        function () use ($slugValue, $locale, $collections) {
            /** @var EntryQueryBuilder $entryQueryBuilder */
            $entryQueryBuilder = EntryFacade::query();

            $entry = $entryQueryBuilder
                ->whereIn('collection', $collections)
                ->where('slug', $slugValue)
                ->where('published', true)
                ->first();

            // get entry in given target locale (defaults to current locale)
            return !is_null($entry) ? $entry->in($locale->value) : null;
        }
    );
}

This piece of code is ran the moment I hit the /en/servicedesk url. $collections in this case can be either an Enum with a single value, or an array. In this example I've already made sure that it's a single string, namely dynamic_pages. However when I check the performance for this in the Laravel debug bar, I see that there are SELECT * FROM entries WHERE collection = ... ; for almost all my collections. Furthermore there are a lot of duplicate queries that seem to try to get the origin of a specific entry (that I am not even querying). I am going to share examples below, what I wanna know though it, why is this happening? Am I doing something wrong? The query it does correctly;

The unnecessary (I think) queries;

A lot of duplicates;

Coming from

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>

geertjanknapen1 commented 1 year ago

There are open PRs to resolve both of these. On 10 May 2023, at 15:26, Geert-Jan Knapen @.*> wrote: I have a piece of code that gets me a certain collection entry, it looks as follows: public function getCollectionEntry(Page|string $slug, Collection|array $collection, ?Locale $locale = null): ?EloquentEntry { $locale = getLocaleEnum($locale); $slugValue = is_string($slug) ? $slug : $slug->value; $collections = is_array($collection) ? collect($collection)->pluck('value')->toArray() : [$collection->value]; $cacheTags = $this->prepareCacheTags($collection); return Cache::tags($cacheTags)->remember( "get_collection_entry:{$locale->value}:$slugValue" . implode('-', $collections), config('custom.caching.ttl'), function () use ($slugValue, $locale, $collections) { /* @var EntryQueryBuilder $entryQueryBuilder / $entryQueryBuilder = EntryFacade::query(); $entry = $entryQueryBuilder ->whereIn('collection', $collections) ->where('slug', $slugValue) ->where('published', true) ->first(); // get entry in given target locale (defaults to current locale) return !is_null($entry) ? $entry->in($locale->value) : null; } ); } This piece of code is ran the moment I hit the /en/servicedesk url. $collections in this case can be either an Enum with a single value, or an array. In this example I've already made sure that it's a single string, namely dynamic_pages. However when I check the performance for this in the Laravel debug bar, I see that there are SELECT FROM entries WHERE collection = ... ; for almost all my collections. Furthermore there are a lot of duplicate queries that seem to try to get the origin of a specific entry (that I am not even querying). I am going to share examples below, what I wanna know though it, why is this happening? Am I doing something wrong? The query it does correctly; The unnecessary (I think) queries; A lot of duplicates; Coming from —Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.>

Can you point me to them?

ryanmitchell commented 1 year ago

https://github.com/statamic/eloquent-driver/pull/123

ryanmitchell commented 1 year ago

And https://github.com/statamic/eloquent-driver/pull/124 I think is the other that is relevent

geertjanknapen1 commented 1 year ago

Right, I think those were created due to my original issue back in January. Is there a timeline regarding when these get actually implemented?

We decided to continue work on other parts first and ignore the issue for a bit, but right now it's such a big problem that we are unable to properly continue our work so some sort of indication would be a lifesaver for me.

jasonvarga commented 1 year ago

Now that Statamic 4.0 is out, we'll try to get to these PRs soon.

ryanmitchell commented 1 year ago

Not something I control I’m afraid. You can pull them in using composer patches if they are a show stopper for you.

geertjanknapen1 commented 1 year ago

I was indeed thinking to implement some composer/vendor patches, however, that solution is not as clean as I would like it to be, hence I was asking for a timeline. But I appreciate the quick replies and clear answers, thanks!