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

perf(db-mongodb): improve performance of all operations, up to 50% faster #9594

Merged
merged 15 commits into from
Dec 19, 2024

Conversation

r1tsuu
Copy link
Member

@r1tsuu r1tsuu commented Nov 28, 2024

This PR improves speed and memory efficiency across all operations with the Mongoose adapter.

How?

  • Removes Mongoose layer from all database calls, instead uses MongoDB directly. (this doesn't remove building mongoose schema since it's still needed for indexes + users in theory can use it)
  • Replaces deep copying of read results using JSON.parse(JSON.stringify(data)) with the transform operation: 'read' function which converts Date's, ObjectID's in relationships / joins to strings. As before, it also handles transformations for write operations.
  • Faster hasNearConstraint for potentially large where's
  • traverseFields now can accept flattenedFields which we use in transform. Less recursive calls with tabs/rows/collapsible

Additional fixes

  • Uses current transaction for querying nested relationships properties in buildQuery, previously it wasn't used which could've led to wrong results
  • Allows to clear not required point fields with passing null from the Local API. Previously it didn't work in both, MongoDB and Postgres

Benchmarks using this file https://github.com/payloadcms/payload/blob/chore/db-benchmark/test/_community/int.spec.ts

Small Dataset Performance

Metric Before Optimization After Optimization Improvement (%)
Average FULL (ms) 1170 844 27.86%
payload.db.create (ms) 1413 691 51.12%
payload.db.find (ms) 2856 2204 22.83%
payload.db.deleteMany (ms) 15206 8439 44.53%
payload.db.updateOne (ms) 21444 12162 43.30%
payload.db.findOne (ms) 159 112 29.56%
payload.db.deleteOne (ms) 3729 2578 30.89%
DB small FULL (ms) 64473 46451 27.93%

Medium Dataset Performance

Metric Before Optimization After Optimization Improvement (%)
Average FULL (ms) 9407 6210 33.99%
payload.db.create (ms) 10270 4321 57.93%
payload.db.find (ms) 20814 16036 22.93%
payload.db.deleteMany (ms) 126351 61789 51.11%
payload.db.updateOne (ms) 201782 99943 50.49%
payload.db.findOne (ms) 1081 817 24.43%
payload.db.deleteOne (ms) 28534 23363 18.12%
DB medium FULL (ms) 519518 342194 34.13%

Large Dataset Performance

Metric Before Optimization After Optimization Improvement (%)
Average FULL (ms) 26575 17509 34.14%
payload.db.create (ms) 29085 12196 58.08%
payload.db.find (ms) 58497 43838 25.04%
payload.db.deleteMany (ms) 372195 173218 53.47%
payload.db.updateOne (ms) 544089 288350 47.00%
payload.db.findOne (ms) 3058 2197 28.14%
payload.db.deleteOne (ms) 82444 64730 21.49%
DB large FULL (ms) 1461097 969714 33.62%

@r1tsuu r1tsuu changed the title perf(db-mongdb): improve performance of all operations, up to 50% faster perf(db-mongodb): improve performance of all operations, up to 50% faster Nov 28, 2024
@r1tsuu r1tsuu force-pushed the perf/use-mongodb-directly branch from 702091e to d2399ed Compare November 29, 2024 13:33
@r1tsuu r1tsuu requested a review from DanRibbens December 3, 2024 21:27
Copy link
Contributor

Choose a reason for hiding this comment

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

Any chance of exporting the transform utility in @payloadcms/db-mongodb for consumers? It would be useful in cases where we need to perform direct operations with mongo/mongoose.

Copy link
Member Author

@r1tsuu r1tsuu Dec 19, 2024

Choose a reason for hiding this comment

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

Don't see why we can't! See 3a68670
Additionally, ensured options.timestamps prop is respected, since it's mongoose-only, I think you use it

I'd say, actually the only problem with exporting things like this is that they aren't meant to be public and may receive breaking changes.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you for considering the timestamps and exporting! The drawback you mention makes sense. I think we have been using mongoose more as an escape hatch when the adaptor doesn't support what we needed. As more options are added to the adaptor (e.g. select, batchsize, timestamps) we could replace some of those usages with the adapter.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it is fine to export it as-is and add an @expiremental flag to the jsdocs so that anyone using this knows it may change in the future.

Copy link
Contributor

@DanRibbens DanRibbens left a comment

Choose a reason for hiding this comment

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

I looked very close at your agregations very closely and it appears you are staying within the API limitations of AWS DocumentDB and Azure Cosmos DB. Great enhancements.

I would only rename the vars cursor to something else since those aren't being used as DB cursors, just an aggregation.
We can add export and experimental flag as a separate PR for @franciscolourenco to use the new transform, though you could do it now if you want.

@r1tsuu r1tsuu force-pushed the perf/use-mongodb-directly branch from 05e7c6f to dda2f20 Compare December 19, 2024 17:15
@DanRibbens DanRibbens merged commit e468292 into main Dec 19, 2024
66 checks passed
@DanRibbens DanRibbens deleted the perf/use-mongodb-directly branch December 19, 2024 18:20
Copy link
Contributor

🚀 This is included in version v3.10.0

r1tsuu added a commit that referenced this pull request Dec 21, 2024
DanRibbens pushed a commit that referenced this pull request Dec 21, 2024
There are few issues introduced in #9594 that we need to look into with
these changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants