diff --git a/src/jrd/Optimizer.cpp b/src/jrd/Optimizer.cpp index 99530fdb55..6a9527b04a 100644 --- a/src/jrd/Optimizer.cpp +++ b/src/jrd/Optimizer.cpp @@ -3462,24 +3462,29 @@ bool OptimizerInnerJoin::cheaperRelationship(IndexRelationship* checkRelationshi * is cheaper as withRelationship. * **************************************/ - if (checkRelationship->cost == 0) { + if (checkRelationship->cost == 0) return true; - } - if (withRelationship->cost == 0) { + + if (withRelationship->cost == 0) return false; - } const double compareValue = checkRelationship->cost / withRelationship->cost; if (compareValue >= 0.98 && compareValue <= 1.02) { - // cost is nearly the same, now check on cardinality - if (checkRelationship->cardinality < withRelationship->cardinality) { - return true; + // cost is nearly the same, now check uniqueness and cardinality + + if (checkRelationship->unique == withRelationship->unique) + { + if (checkRelationship->cardinality < withRelationship->cardinality) + return true; } + else if (checkRelationship->unique) + return true; + else if (withRelationship->unique) + return false; } - else if (checkRelationship->cost < withRelationship->cost) { + else if (checkRelationship->cost < withRelationship->cost) return true; - } return false; } @@ -3786,20 +3791,22 @@ void OptimizerInnerJoin::getIndexedRelationship(InnerJoinStreamInfo* baseStream, indexRelationship->stream = testStream->stream; indexRelationship->unique = candidate->unique; indexRelationship->cost = candidate->cost; - indexRelationship->cardinality = csb_tail->csb_cardinality * candidate->selectivity; + indexRelationship->cardinality = candidate->unique ? + csb_tail->csb_cardinality : csb_tail->csb_cardinality * candidate->selectivity; // indexRelationship are kept sorted on cost and unique in the indexRelations array. - // The unique and cheapest indexed relatioships are on the first position. + // The unique and cheapest indexed relationships are on the first position. size_t index = 0; for (; index < baseStream->indexedRelationships.getCount(); index++) { - if (cheaperRelationship(indexRelationship, baseStream->indexedRelationships[index])) { + if (cheaperRelationship(indexRelationship, baseStream->indexedRelationships[index])) break; - } } + baseStream->indexedRelationships.insert(index, indexRelationship); testStream->previousExpectedStreams++; } + delete candidate; delete optimizerRetrieval;