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

Fix to prevent double hydration #30

Open
wants to merge 1 commit into
base: 1.2
Choose a base branch
from
Open

Fix to prevent double hydration #30

wants to merge 1 commit into from

Conversation

gstjohn
Copy link

@gstjohn gstjohn commented Mar 26, 2018

Hey @rsanchez, while using Deep we started to see pulling models for complex entries take a fairly significant amount of time to populate (on the order of 50 secs). I dove into the specifics of the addon and discovered that due, in part, to Eloquent that models are hydrating twice. See query log:

select * from `exp_channels`;
select * from `exp_channel_titles` inner join `exp_channel_data` on `exp_channel_titles`.`entry_id` = `exp_channel_data`.`entry_id` left join `exp_fm_search_channels` on `exp_channel_titles`.`channel_id` = `exp_fm_search_channels`.`channel_id` where `exp_channel_titles`.`entry_id` in ( "68362" ) and (select count(*) from `exp_categories` inner join `exp_category_posts` on `exp_category_posts`.`cat_id` = `exp_categories`.`cat_id` where `exp_channel_titles`.`entry_id` = `exp_category_posts`.`entry_id` and `exp_categories`.`cat_id` in (586, 60)) = 0;
select * from `exp_channel_fields` order by field_type IN ('matrix', 'grid') DESC, field_type IN ('playa', 'relationship') DESC, `field_order` asc;
select * from `exp_grid_columns` where `field_id` in ( "439" , "531" ) order by `col_order` asc;
select * from `exp_channel_titles` inner join `exp_channel_data` on `exp_channel_titles`.`entry_id` = `exp_channel_data`.`entry_id` inner join `exp_relationships` on `exp_relationships`.`child_id` = `exp_channel_titles`.`entry_id` where `exp_relationships`.`parent_id` in (68362) order by `order` asc;
select * from `exp_channel_grid_field_439` where `entry_id` in (68362) order by `row_order` asc;
select * from `exp_channel_grid_field_531` where `entry_id` in (68362) order by `row_order` asc;
select * from `exp_files`;
select * from `exp_upload_prefs`;
select * from `exp_grid_columns` where `field_id` in ( "439" , "531" ) order by `col_order` asc;
select * from `exp_channel_titles` inner join `exp_channel_data` on `exp_channel_titles`.`entry_id` = `exp_channel_data`.`entry_id` inner join `exp_relationships` on `exp_relationships`.`child_id` = `exp_channel_titles`.`entry_id` where `exp_relationships`.`parent_id` in (68362) order by `order` asc;
select * from `exp_channel_grid_field_439` where `entry_id` in (68362) order by `row_order` asc;
select * from `exp_channel_grid_field_531` where `entry_id` in (68362) order by `row_order` asc;
select * from `exp_files`;

You'll see that there are 4 queries that repeat and this is due to the call to $builder->getModels($columns) and then later to $builder->getModel()->newCollection($models) in Builder.php::get(). Both of these end up calling for a newCollection() on the model which on the Entry model results in multiple calls to $this->hydrateCollection($collection).

To fix this issue, I added a state check to the Collections which indicates if they have been hydrated. What this does is allows the call to $builder->getModels($columns) to do the initial hydration it needs to do, but skips it on the second pass while calling $builder->getModel()->newCollection($models). The isHydrated() method is not cached which would allow for any non-hydrated additions to the collection to classify the entire collection as unhydrated and would force another set up queries and population of the models.

Let me know if there is anything further I can do here, but we saw it make a 50% speed improvement in our application. Thanks!

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.

None yet

1 participant