Skip to content
Snippets Groups Projects

Performance increase for cardinality unlimited fields

1 file
+ 20
21
Compare changes
  • Side-by-side
  • Inline
@@ -55,13 +55,11 @@ class EntityReferenceIntegrityEntityHandler implements EntityHandlerInterface, E
// Select a count of all entities of type $source_entity_type_id which
// have any one of their entity reference fields pointing to the given
// entity.
$number_of_referencing_entities = $this->referentialEntityQuery($source_entity_type_id, $source_fields, $entity->id())
->count()
->execute();
$referencing_entity_ids = $this->referentialEntityIds($source_entity_type_id, $source_fields, $entity);
// Stop immediately if we find any foreign entity which references our own
// entity.
if ($number_of_referencing_entities > 0) {
if ($referencing_entity_ids) {
return TRUE;
}
}
@@ -76,7 +74,7 @@ class EntityReferenceIntegrityEntityHandler implements EntityHandlerInterface, E
$referencing_entities = [];
$referencing_fields = $this->fieldMap->getReferencingFields($entity->getEntityTypeId());
foreach ($referencing_fields as $source_entity_type_id => $source_fields) {
$entity_ids = array_values($this->referentialEntityQuery($source_entity_type_id, $source_fields, $entity->id())->execute());
$entity_ids = $this->referentialEntityIds($source_entity_type_id, $source_fields, $entity);
if (!empty($entity_ids)) {
$referencing_entities[$source_entity_type_id] = $entity_ids;
}
@@ -91,35 +89,36 @@ class EntityReferenceIntegrityEntityHandler implements EntityHandlerInterface, E
$entities = $this->getDependentEntityIds($entity);
$loaded_entities = [];
foreach ($entities as $entity_type_id => $ids) {
$loaded_entities[$entity_type_id] = array_values($this->entityTypeManager->getStorage($entity_type_id)->loadMultiple($ids));
$loaded_entities[$entity_type_id] = array_values($this->entityTypeManager->getStorage($entity_type_id)
->loadMultiple($ids));
}
return $loaded_entities;
}
/**
* Start an entity query for entities matching set conditions.
*
* Query for all entities of the specified type which have any fields in the
* source field list that match the given target ID.
* Return all entity ids of the specified type which have any fields in the
* source field list that match the given target entity ID.
*
* @param string $entity_type
* The entityt type.
* The entity type.
* @param array $source_fields
* An array of source fields.
* @param string|int $target_id
* The target ID to search for.
* @param \Drupal\Core\Entity\ContentEntityInterface $target_entity
* The target entity to search for
*
* @return \Drupal\Core\Entity\Query\QueryInterface
* A query object.
* @return array
* The referencing entity ids for the entity type
*/
protected function referentialEntityQuery($entity_type, array $source_fields, $target_id) {
$query = $this->entityTypeManager->getStorage($entity_type)->getQuery();
$or_group = $query->orConditionGroup();
protected function referentialEntityIds($entity_type, array $source_fields, $target_entity) {
$entity_store = $this->entityTypeManager->getStorage($entity_type);
$ids = [];
foreach ($source_fields as $source_field) {
$or_group->condition($source_field, $target_id, '=');
// Don't use OR query for performance reasons (would create too many joins)
$query = $entity_store->getQuery();
$query->condition($source_field, $target_entity->id(), '=');
$ids += array_flip($query->execute());
}
$query->condition($or_group);
return $query;
return array_keys($ids);
}
/**
Loading