Skip to content
Snippets Groups Projects
Commit f6aa1756 authored by Andy Yates's avatar Andy Yates
Browse files

[ENSCORESW-757]. Cannot perform a fast query on two OR fields from the same table.

Our lookups of primary accessions and display labels with the Xref table was
flawed. Seems MySQL can only use 1 index per query and it is not possible to
create a single index that can handle querying on two columns when either
could be our matching value. Solution is to break the query into two parts
each targetting a single column. MySQL is a lot happier about this and
query times have dropped from 30 seconds on USEast to 18ms (9ms per query).
parent 0076a179
No related branches found
No related tags found
No related merge requests found
...@@ -1824,24 +1824,34 @@ SQL ...@@ -1824,24 +1824,34 @@ SQL
. ' AND xdb.external_db_id = x.external_db_id AND'; . ' AND xdb.external_db_id = x.external_db_id AND';
} }
my $query1 = qq( my @queries;
SELECT $ID_sql push (@queries, qq(
FROM $from_sql SELECT $ID_sql
xref x, FROM $from_sql
object_xref oxr xref x,
WHERE $where_sql object_xref oxr
( x.dbprimary_acc $comparison_operator ? OR x.display_label $comparison_operator ? ) WHERE $where_sql
AND x.xref_id = oxr.xref_id x.dbprimary_acc $comparison_operator ?
AND oxr.ensembl_object_type = ? AND x.xref_id = oxr.xref_id
); AND oxr.ensembl_object_type = ?
));
my $query2;
push (@queries, qq(
SELECT $ID_sql
FROM $from_sql
xref x,
object_xref oxr
WHERE $where_sql
x.display_label $comparison_operator ?
AND x.xref_id = oxr.xref_id
AND oxr.ensembl_object_type = ?
));
if ( defined($external_db_name) ) { if ( defined($external_db_name) ) {
# If we are given the name of an external database, we need to join # If we are given the name of an external database, we need to join
# between the 'xref' and the 'object_xref' tables on 'xref_id'. # between the 'xref' and the 'object_xref' tables on 'xref_id'.
$query2 = qq( push (@queries, qq(
SELECT $ID_sql SELECT $ID_sql
FROM $from_sql FROM $from_sql
external_synonym syn, external_synonym syn,
...@@ -1851,13 +1861,13 @@ SQL ...@@ -1851,13 +1861,13 @@ SQL
syn.synonym $comparison_operator ? syn.synonym $comparison_operator ?
AND syn.xref_id = oxr.xref_id AND syn.xref_id = oxr.xref_id
AND oxr.ensembl_object_type = ? AND oxr.ensembl_object_type = ?
AND x.xref_id = oxr.xref_id); AND x.xref_id = oxr.xref_id));
} else { } else {
# If we weren't given an external database name, we can get away # If we weren't given an external database name, we can get away
# with less joins here. # with less joins here.
$query2 = qq( push (@queries, qq(
SELECT $ID_sql SELECT $ID_sql
FROM $from_sql FROM $from_sql
external_synonym syn, external_synonym syn,
...@@ -1865,32 +1875,21 @@ SQL ...@@ -1865,32 +1875,21 @@ SQL
WHERE $where_sql WHERE $where_sql
syn.synonym $comparison_operator ? syn.synonym $comparison_operator ?
AND syn.xref_id = oxr.xref_id AND syn.xref_id = oxr.xref_id
AND oxr.ensembl_object_type = ?); AND oxr.ensembl_object_type = ?));
} }
my %result; my %result;
my $h = $self->dbc()->sql_helper();
my $sth = $self->prepare($query1); my @params = ([$name, SQL_VARCHAR], [$ensType, SQL_VARCHAR]);
unshift(@params, [$self->species_id(), SQL_INTEGER] ) if $multispecies;
my $queryBind = 1; foreach my $query (@queries) {
$sth->bind_param( $queryBind++, $self->species_id(), SQL_INTEGER ) if $multispecies; $h->execute_no_return(-SQL => $query, -PARAMS => \@params, -CALLBACK => sub {
$sth->bind_param( $queryBind++, $name, SQL_VARCHAR ); my ($row) = @_;
$sth->bind_param( $queryBind++, $name, SQL_VARCHAR ); my ($id) = @{$row};
$sth->bind_param( $queryBind++, $ensType, SQL_VARCHAR ); $result{$id} = 1;
$sth->execute(); });
my $r; }
while ( $r = $sth->fetchrow_array() ) { $result{$r} = 1 }
$sth = $self->prepare($query2);
$queryBind = 1;
$sth->bind_param( $queryBind++, $self->species_id(), SQL_INTEGER ) if $multispecies;
$sth->bind_param( $queryBind++, $name, SQL_VARCHAR );
$sth->bind_param( $queryBind++, $ensType, SQL_VARCHAR );
$sth->execute();
while ( $r = $sth->fetchrow_array() ) { $result{$r} = 1 }
return keys(%result); return keys(%result);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment