@@ -, +, @@ queries - Always prefetch item data so that `$c->item` does not execute an additional SQL query at every iteration of the loop. Item data is always needed at the first line of the loop, so there is really no downside for doing this. - Build the `@types` array only once, out of the checkouts loop. Since it does not depend at all on patron's checkouts data, it does not make sense to build it inside the loop. I tested with 1000 checkouts, but the slowness should be noticeable with less. and the item(s) you will check out for testing) with a maximum number of checkouts allowed time it takes. used in step 3). Measure the time it takes and compare it to step 3. It should be faster now. --- C4/Circulation.pm | 64 ++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 28 deletions(-) --- a/C4/Circulation.pm +++ a/C4/Circulation.pm @@ -451,47 +451,55 @@ sub TooMany { $checkouts = $patron->checkouts; # if branch is the patron's home branch, then count all loans by patron } else { $checkouts = $patron->checkouts->search( - { 'item.homebranch' => $maxissueqty_rule->branchcode }, - { prefetch => 'item' } ); + { 'item.homebranch' => $maxissueqty_rule->branchcode } ); } } else { $checkouts = $patron->checkouts; # if rule is not branch specific then count all loans by patron } + $checkouts = $checkouts->search(undef, { prefetch => 'item' }); + my $sum_checkouts; my $rule_itemtype = $maxissueqty_rule->itemtype; - while ( my $c = $checkouts->next ) { - my $itemtype = $c->item->effective_itemtype; - my @types; - unless ( $rule_itemtype ) { - # matching rule has the default item type, so count only - # those existing loans that don't fall under a more - # specific rule - @types = Koha::CirculationRules->search( - { - branchcode => $maxissueqty_rule->branchcode, - categorycode => [ $maxissueqty_rule->categorycode, $cat_borrower ], - itemtype => { '!=' => undef }, - rule_name => 'maxissueqty' - } - )->get_column('itemtype'); - next if grep {$_ eq $itemtype} @types; - } else { - my @types; - if ( $parent_maxissueqty_rule ) { + my @types; + unless ( $rule_itemtype ) { + # matching rule has the default item type, so count only + # those existing loans that don't fall under a more + # specific rule + @types = Koha::CirculationRules->search( + { + branchcode => $maxissueqty_rule->branchcode, + categorycode => [ $maxissueqty_rule->categorycode, $cat_borrower ], + itemtype => { '!=' => undef }, + rule_name => 'maxissueqty' + } + )->get_column('itemtype'); + } else { + if ( $parent_maxissueqty_rule ) { # if we have a parent item type then we count loans of the # specific item type or its siblings or parent - my $children = Koha::ItemTypes->search({ parent_type => $parent_type }); - @types = $children->get_column('itemtype'); - push @types, $parent_type; - } elsif ( $child_types ) { + my $children = Koha::ItemTypes->search({ parent_type => $parent_type }); + @types = $children->get_column('itemtype'); + push @types, $parent_type; + } elsif ( $child_types ) { # If we are a parent type, we need to count all child types and our own type - @types = $child_types->get_column('itemtype'); - push @types, $type; # And don't forget to count our own types - } else { push @types, $type; } # Otherwise only count the specific itemtype + @types = $child_types->get_column('itemtype'); + push @types, $type; # And don't forget to count our own types + } else { + # Otherwise only count the specific itemtype + push @types, $type; + } + } + + while ( my $c = $checkouts->next ) { + my $itemtype = $c->item->effective_itemtype; + unless ( $rule_itemtype ) { + next if grep {$_ eq $itemtype} @types; + } else { next unless grep {$_ eq $itemtype} @types; } + $sum_checkouts->{total}++; $sum_checkouts->{onsite_checkouts}++ if $c->onsite_checkout; $sum_checkouts->{itemtype}->{$itemtype}++; --