should be faster than using IN on large lists

This commit is contained in:
Oliver Gorwits
2019-12-21 21:31:34 +00:00
parent 9a1938ddc9
commit 0eab9213c0
2 changed files with 38 additions and 16 deletions

View File

@@ -0,0 +1,33 @@
use utf8;
package App::Netdisco::DB::Result::Virtual::PortMacs;
use strict;
use warnings;
use base 'DBIx::Class::Core';
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
__PACKAGE__->table("port_macs");
__PACKAGE__->result_source_instance->is_virtual(1);
__PACKAGE__->result_source_instance->view_definition(<<ENDSQL
SELECT all.ip, all.mac
FROM
(SELECT ip, mac FROM device
UNION
SELECT ip, mac FROM device_port) all
INNER JOIN
(SELECT unnest( ? )) locals(m)
ON (all.mac = locals.m ::macaddr)
ENDSQL
);
__PACKAGE__->add_columns(
'mac' => { data_type => 'macaddr' },
'ip' => { data_type => 'inet' },
);
1;

View File

@@ -33,22 +33,11 @@ sub get_port_macs {
my $port_macs = {}; my $port_macs = {};
return {} unless defined $fw_mac_list and ref [] eq ref $fw_mac_list; return {} unless defined $fw_mac_list and ref [] eq ref $fw_mac_list;
my $dp_macs my $macs
= schema('netdisco')->resultset('DevicePort') = schema('netdisco')->resultset('Virtual::PortMacs')->search({},
->search( { mac => { '-in' => $fw_mac_list } }, { bind => [$fw_mac_list], select => [ 'mac', 'ip' ], group_by => [ 'mac', 'ip' ] } );
{ select => [ 'mac', 'ip' ], my $cursor = $macs->cursor;
group_by => [ 'mac', 'ip' ] } ); while ( my @vals = $cursor->next ) {
my $dp_cursor = $dp_macs->cursor;
while ( my @vals = $dp_cursor->next ) {
$port_macs->{ $vals[0] } = $vals[1];
}
my $d_macs
= schema('netdisco')->resultset('Device')
->search( { mac => { '-in' => $fw_mac_list } },
{ select => [ 'mac', 'ip' ] } );
my $d_cursor = $d_macs->cursor;
while ( my @vals = $d_cursor->next ) {
$port_macs->{ $vals[0] } = $vals[1]; $port_macs->{ $vals[0] } = $vals[1];
} }