Only add the joins to the parts table filter query if they are really required

This should improve the performance of the queries slightly
This commit is contained in:
Jan Böhmer 2024-02-25 01:40:25 +01:00
parent b176cb1ae1
commit fbd095ab50
3 changed files with 57 additions and 22 deletions

View file

@ -115,31 +115,31 @@ class PartFilter implements FilterInterface
*/ */
//We have to use Having here, as we use an alias column which is not supported on the where clause and would result in an error //We have to use Having here, as we use an alias column which is not supported on the where clause and would result in an error
$this->amountSum = (new IntConstraint('amountSum'))->useHaving(); $this->amountSum = (new IntConstraint('amountSum'))->useHaving();
$this->lotCount = new IntConstraint('COUNT(partLots)'); $this->lotCount = new IntConstraint('COUNT(_partLots)');
$this->lessThanDesired = new LessThanDesiredConstraint(); $this->lessThanDesired = new LessThanDesiredConstraint();
$this->storelocation = new EntityConstraint($nodesListBuilder, StorageLocation::class, 'partLots.storage_location'); $this->storelocation = new EntityConstraint($nodesListBuilder, StorageLocation::class, '_partLots.storage_location');
$this->lotNeedsRefill = new BooleanConstraint('partLots.needs_refill'); $this->lotNeedsRefill = new BooleanConstraint('_partLots.needs_refill');
$this->lotUnknownAmount = new BooleanConstraint('partLots.instock_unknown'); $this->lotUnknownAmount = new BooleanConstraint('_partLots.instock_unknown');
$this->lotExpirationDate = new DateTimeConstraint('partLots.expiration_date'); $this->lotExpirationDate = new DateTimeConstraint('_partLots.expiration_date');
$this->lotDescription = new TextConstraint('partLots.description'); $this->lotDescription = new TextConstraint('_partLots.description');
$this->lotOwner = new EntityConstraint($nodesListBuilder, User::class, 'partLots.owner'); $this->lotOwner = new EntityConstraint($nodesListBuilder, User::class, '_partLots.owner');
$this->manufacturer = new EntityConstraint($nodesListBuilder, Manufacturer::class, 'part.manufacturer'); $this->manufacturer = new EntityConstraint($nodesListBuilder, Manufacturer::class, 'part.manufacturer');
$this->manufacturer_product_number = new TextConstraint('part.manufacturer_product_number'); $this->manufacturer_product_number = new TextConstraint('part.manufacturer_product_number');
$this->manufacturer_product_url = new TextConstraint('part.manufacturer_product_url'); $this->manufacturer_product_url = new TextConstraint('part.manufacturer_product_url');
$this->manufacturing_status = new ChoiceConstraint('part.manufacturing_status'); $this->manufacturing_status = new ChoiceConstraint('part.manufacturing_status');
$this->attachmentsCount = new IntConstraint('COUNT(attachments)'); $this->attachmentsCount = new IntConstraint('COUNT(_attachments)');
$this->attachmentType = new EntityConstraint($nodesListBuilder, AttachmentType::class, 'attachments.attachment_type'); $this->attachmentType = new EntityConstraint($nodesListBuilder, AttachmentType::class, '_attachments.attachment_type');
$this->attachmentName = new TextConstraint('attachments.name'); $this->attachmentName = new TextConstraint('_attachments.name');
$this->supplier = new EntityConstraint($nodesListBuilder, Supplier::class, 'orderdetails.supplier'); $this->supplier = new EntityConstraint($nodesListBuilder, Supplier::class, '_orderdetails.supplier');
$this->orderdetailsCount = new IntConstraint('COUNT(orderdetails)'); $this->orderdetailsCount = new IntConstraint('COUNT(_orderdetails)');
$this->obsolete = new BooleanConstraint('orderdetails.obsolete'); $this->obsolete = new BooleanConstraint('_orderdetails.obsolete');
$this->parameters = new ArrayCollection(); $this->parameters = new ArrayCollection();
$this->parametersCount = new IntConstraint('COUNT(parameters)'); $this->parametersCount = new IntConstraint('COUNT(_parameters)');
} }
public function apply(QueryBuilder $queryBuilder): void public function apply(QueryBuilder $queryBuilder): void

View file

@ -82,7 +82,7 @@ class PartSearchFilter implements FilterInterface
$fields_to_search[] = 'part.name'; $fields_to_search[] = 'part.name';
} }
if($this->category) { if($this->category) {
$fields_to_search[] = 'category.name'; $fields_to_search[] = '_category.name';
} }
if($this->description) { if($this->description) {
$fields_to_search[] = 'part.description'; $fields_to_search[] = 'part.description';
@ -94,22 +94,22 @@ class PartSearchFilter implements FilterInterface
$fields_to_search[] = 'part.tags'; $fields_to_search[] = 'part.tags';
} }
if($this->storelocation) { if($this->storelocation) {
$fields_to_search[] = 'storelocations.name'; $fields_to_search[] = '_storelocations.name';
} }
if($this->ordernr) { if($this->ordernr) {
$fields_to_search[] = 'orderdetails.supplierpartnr'; $fields_to_search[] = '_orderdetails.supplierpartnr';
} }
if($this->mpn) { if($this->mpn) {
$fields_to_search[] = 'part.manufacturer_product_number'; $fields_to_search[] = 'part.manufacturer_product_number';
} }
if($this->supplier) { if($this->supplier) {
$fields_to_search[] = 'suppliers.name'; $fields_to_search[] = '_suppliers.name';
} }
if($this->manufacturer) { if($this->manufacturer) {
$fields_to_search[] = 'manufacturer.name'; $fields_to_search[] = '_manufacturer.name';
} }
if($this->footprint) { if($this->footprint) {
$fields_to_search[] = 'footprint.name'; $fields_to_search[] = '_footprint.name';
} }
if ($this->ipn) { if ($this->ipn) {
$fields_to_search[] = 'part.ipn'; $fields_to_search[] = 'part.ipn';

View file

@ -241,7 +241,7 @@ final class PartsDataTable implements DataTableTypeInterface
) AS HIDDEN amountSum' ) AS HIDDEN amountSum'
) )
->from(Part::class, 'part') ->from(Part::class, 'part')
->leftJoin('part.category', 'category') /*->leftJoin('part.category', 'category')
->leftJoin('part.master_picture_attachment', 'master_picture_attachment') ->leftJoin('part.master_picture_attachment', 'master_picture_attachment')
->leftJoin('part.partLots', 'partLots') ->leftJoin('part.partLots', 'partLots')
->leftJoin('partLots.storage_location', 'storelocations') ->leftJoin('partLots.storage_location', 'storelocations')
@ -252,7 +252,7 @@ final class PartsDataTable implements DataTableTypeInterface
->leftJoin('orderdetails.supplier', 'suppliers') ->leftJoin('orderdetails.supplier', 'suppliers')
->leftJoin('part.attachments', 'attachments') ->leftJoin('part.attachments', 'attachments')
->leftJoin('part.partUnit', 'partUnit') ->leftJoin('part.partUnit', 'partUnit')
->leftJoin('part.parameters', 'parameters') ->leftJoin('part.parameters', 'parameters')*/
//This must be the only group by, or the paginator will not work correctly //This must be the only group by, or the paginator will not work correctly
->addGroupBy('part.id'); ->addGroupBy('part.id');
@ -339,5 +339,40 @@ final class PartsDataTable implements DataTableTypeInterface
$filter = $options['filter']; $filter = $options['filter'];
$filter->apply($builder); $filter->apply($builder);
} }
//Check if the query contains certain conditions, for which we need to add additional joins
//The join fields get prefixed with an underscore, so we can check if they are used in the query easy without confusing them for a part subfield
$dql = $builder->getDQL();
if (str_contains($dql, '_category')) {
$builder->leftJoin('part.category', '_category');
}
if (str_contains($dql, '_master_picture_attachment')) {
$builder->leftJoin('part.master_picture_attachment', '_master_picture_attachment');
}
if (str_contains($dql, '_partLots') || str_contains($dql, '_storelocations')) {
$builder->leftJoin('part.partLots', '_partLots');
$builder->leftJoin('_partLots.storage_location', '_storelocations');
}
if (str_contains($dql, '_footprint')) {
$builder->leftJoin('part.footprint', '_footprint');
}
if (str_contains($dql, '_manufacturer')) {
$builder->leftJoin('part.manufacturer', '_manufacturer');
}
if (str_contains($dql, '_orderdetails') || str_contains($dql, '_suppliers')) {
$builder->leftJoin('part.orderdetails', '_orderdetails');
$builder->leftJoin('_orderdetails.supplier', '_suppliers');
}
if (str_contains($dql, '_attachments')) {
$builder->leftJoin('part.attachments', '_attachments');
}
if (str_contains($dql, '_partUnit')) {
$builder->leftJoin('part.partUnit', '_partUnit');
}
if (str_contains($dql, '_parameters')) {
$builder->leftJoin('part.parameters', '_parameters');
}
} }
} }