Optimisation
How to speed up your queries.
ORMs can be slow and cumbersome, especially when dealing with complex nested hierarchies of entities and recursive relationships. A simple mistake or oversight defining your object relationships can cause the ORM to end up doing far more work than is necessary. Here are some things you can check to see if you can squeeze more speed out of Objectiphy.
Enable production mode. Various performance improvements are automatically applied when Objectiphy runs in production mode, as it is assumed that your entities will not be modified in production (thus allowing mapping information to be cached between requests), and that you will not need to debug the queries that are run. See the quick start page for information on production mode. Note: Objectiphy's integration tests run about 4 times faster in production mode than in dev mode, so do make sure you set this flag correctly for your environment.
Use an in-memory persistent cache. Using a cache such as Redis instead of the build-in file-system cache can give you better performance, especially in production.
Use lazy loading. If not all child objects are likely to be needed, lazy loading can save a significant amount of time.
Use eager loading. If all child objects are likely to be needed, eager loading will save time for one-to-one and many-to-one relationships, as the data for the child objects can be retrieved at the same time as the parent, using joins.
Set the max depth. You might find performance benefits from setting the maxDepth configuration option to a lower value (it defaults to 3) - it depends what you do with the results, ie. whether or not you intend to access every property in the entire hierarchy (for example by serializing the result) - if you do need to access the whole hierarchy, you should set it to zero (which means unlimited).
Disable deletes. You can disable deletion via a configuration option to prevent Objectiphy from deleting relationships and/or entities. Disabling deletes can improve performance a little, as Objectiphy does not have to check whether anything has been removed.
Use partial hydration. If you don't need to hydrate everything, use a select query to specify which fields to fetch.
Use serialization groups. If you are serializing your entities and using serialization groups to limit which fields are output, use the serialization groups config option to tell Objectiphy which groups you are using, and it will only hydrate what you need.
Use pagination. Only load a subset of records at a time.
Check your relationship definitions. Make sure you are not inadvertently loading more data than you need in your mapping definitions. If an entity has a reference to its parent, and the parent has a one-to-many of all its children, loading one child could cause all of its siblings to be loaded too.
Filter results. Use criteria to narrow down the records to be returned.
Use indexes. Make sure any columns in your database that act as foreign keys or are used for filtering have indexes on them.
Stream results. If dealing with large amounts of data, fetch on demand will prevent you from using up too much memory - this is particularly useful for things like CSV exports, where you don't want pagination.
Don't update children. When saving a parent entity, if you know what has changed, set the
$saveChildren
flag to false on the call tosaveEntity
, and save the entities that have changed individually. This saves Objectiphy having to traverse the entire object model structure to check what has changed.
Last updated