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
This commit is contained in:
@@ -11,17 +11,9 @@ __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
|||||||
__PACKAGE__->table("port_macs");
|
__PACKAGE__->table("port_macs");
|
||||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||||
__PACKAGE__->result_source_instance->view_definition(<<ENDSQL
|
__PACKAGE__->result_source_instance->view_definition(<<ENDSQL
|
||||||
SELECT dp.ip, dp.mac
|
SELECT ip, mac FROM device where mac = any (?::macaddr[])
|
||||||
|
|
||||||
FROM
|
|
||||||
(SELECT ip, mac FROM device
|
|
||||||
UNION
|
UNION
|
||||||
SELECT ip, mac FROM device_port) dp
|
SELECT ip, mac FROM device_port dp where mac = any (?::macaddr[])
|
||||||
|
|
||||||
INNER JOIN
|
|
||||||
(SELECT unnest( ? ::macaddr[] )) locals(m)
|
|
||||||
ON (dp.mac = locals.m ::macaddr)
|
|
||||||
|
|
||||||
ENDSQL
|
ENDSQL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ sub get_port_macs {
|
|||||||
|
|
||||||
my $macs
|
my $macs
|
||||||
= schema('netdisco')->resultset('Virtual::PortMacs')->search({},
|
= schema('netdisco')->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;
|
my $cursor = $macs->cursor;
|
||||||
while ( my @vals = $cursor->next ) {
|
while ( my @vals = $cursor->next ) {
|
||||||
$port_macs->{ $vals[0] } = $vals[1];
|
$port_macs->{ $vals[0] } = $vals[1];
|
||||||
|
|||||||
Reference in New Issue
Block a user