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__->result_source_instance->is_virtual(1);
|
||||
__PACKAGE__->result_source_instance->view_definition(<<ENDSQL
|
||||
SELECT dp.ip, dp.mac
|
||||
|
||||
FROM
|
||||
(SELECT ip, mac FROM device
|
||||
SELECT ip, mac FROM device where mac = any (?::macaddr[])
|
||||
UNION
|
||||
SELECT ip, mac FROM device_port) dp
|
||||
|
||||
INNER JOIN
|
||||
(SELECT unnest( ? ::macaddr[] )) locals(m)
|
||||
ON (dp.mac = locals.m ::macaddr)
|
||||
|
||||
SELECT ip, mac FROM device_port dp where mac = any (?::macaddr[])
|
||||
ENDSQL
|
||||
);
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ sub get_port_macs {
|
||||
|
||||
my $macs
|
||||
= 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;
|
||||
while ( my @vals = $cursor->next ) {
|
||||
$port_macs->{ $vals[0] } = $vals[1];
|
||||
|
||||
Reference in New Issue
Block a user