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

Introduce new batch update for settings reduces the number of queries sent to the database and redis #213

Merged
merged 4 commits into from
Apr 28, 2023

Conversation

AhmedAli-Qawafel
Copy link
Contributor

@AhmedAli-Qawafel AhmedAli-Qawafel commented Mar 31, 2023

The purpose of this pull request is to improve the performance of database updates discussed here, by grouping records by their respective groups and performing batch updates on each group. Instead of saving each record in a single query, this approach sends a single request per group, resulting in faster and more efficient updates at the database level.
It is safe to use this feature because it includes error handling that falls back to the original save logic in the event of any issues. This ensures that data is not lost and that the application can continue to function correctly even if an error occurs during the save process.

@AhmedAli-Qawafel AhmedAli-Qawafel changed the title Introduce new batch update for settings reduces the number of queries sent to the database Introduce new batch update for settings reduces the number of queries sent to the database and redis Apr 1, 2023
@AhmedAli-Qawafel
Copy link
Contributor Author

@rubenvanassche any update on this?

Copy link
Member

@rubenvanassche rubenvanassche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some changes required, but looking good!

$propertiesToUpdate = $properties
->reject(fn ($payload, string $name) => $config->isLocked($name));

(clone $propertiesToUpdate)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would you add a clone here?

Copy link
Contributor Author

@AhmedAli-Qawafel AhmedAli-Qawafel Apr 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're correct that there's no need to use clone, as reject returns a new filtered collection.

'payload' => $payload,
];
})
->groupBy('group')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this required, we're saving one settings class so we'll always have one group right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're correct that there's no need to group, since it will always have one group.

})->toArray();

try {
$this->getBuilder()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let us let it fail hard, no need to catch this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -71,6 +73,25 @@ public function updatePropertyPayload(string $group, string $name, $value): void
]);
}

public function updatePropertiesPayload(string $group, Collection $properties): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this will be a major release, could we drop updatePropertyPayload altogether to make a unified update path in the code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -71,6 +73,25 @@ public function updatePropertyPayload(string $group, string $name, $value): void
]);
}

public function updatePropertiesPayload(string $group, Collection $properties): void
{
$propertiesInBatch = (clone $properties)->map(function ($property) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's drop the clone here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

{
$data = [];

$properties->each(function (array $property) use ($group, &$data) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we rewrite this as a mapWithKeys?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

$table->json('payload');

$table->timestamps();

$table->unique(['group', 'name']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea 👍

@AhmedAli-Qawafel
Copy link
Contributor Author

"Hi @rubenvanassche ,

I've made the changes you suggested in my code and I wanted to ask if you could take another look at it when you have a chance. I'd really appreciate your feedback on the changes I've made.

Thank you

@rubenvanassche
Copy link
Member

Thanks!

@rubenvanassche rubenvanassche merged commit 487b0ad into spatie:main Apr 28, 2023
@AhmedAli-Qawafel
Copy link
Contributor Author

Hey, on the contrary we have added a default value for that field to be false on this pull request so it doesn't matter if it's not sent to the database it already have a default value we migrated our live project and it's working fine with the new updates kindly send me a trace or the called method please

@jswansonEA
Copy link

I just realized I hadn't published the new migration after upgrading to version 3. Thanks for the quick response.

@AhmedAli-Qawafel
Copy link
Contributor Author

Pleasure to help 🙏

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

3 participants