From 031c3e6d956b65722f27c3302323a9cbf09e9633 Mon Sep 17 00:00:00 2001 From: Christian Ramseyer Date: Fri, 31 Jan 2020 10:32:02 +0100 Subject: [PATCH] Optimize PortMAC query * We meant well but it turns out that the array unnest and join is actually very slow, as the join arguments do not get pushed down into the CTE (in Postgres 9/10 at least, later versions remove some of the optimization barriers in that specifc type of query) * This caused a seq scan on both device and device_port, and the query is executed many times during macsuck * The query is now rewritten to use ANY (macaddr[]) and without CTE, which seems to be around 20x faster --- lib/App/Netdisco/DB/Result/Virtual/PortMacs.pm | 12 ++---------- lib/App/Netdisco/Util/PortMAC.pm | 2 +- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/lib/App/Netdisco/DB/Result/Virtual/PortMacs.pm b/lib/App/Netdisco/DB/Result/Virtual/PortMacs.pm index 3e29cb2e..212530d5 100644 --- a/lib/App/Netdisco/DB/Result/Virtual/PortMacs.pm +++ b/lib/App/Netdisco/DB/Result/Virtual/PortMacs.pm @@ -11,17 +11,9 @@ __PACKAGE__->table_class('DBIx::Class::ResultSource::View'); __PACKAGE__->table("port_macs"); __PACKAGE__->result_source_instance->is_virtual(1); __PACKAGE__->result_source_instance->view_definition(<resultset('Virtual::PortMacs')->search({}, - { bind => [$bindarray], select => [ 'mac', 'ip' ], group_by => [ 'mac', 'ip' ] } ); + { bind => [$bindarray, $bindarray], select => [ 'mac', 'ip' ], group_by => [ 'mac', 'ip' ] } ); my $cursor = $macs->cursor; while ( my @vals = $cursor->next ) { $port_macs->{ $vals[0] } = $vals[1];