MCPcopy Create free account
hub / github.com/FirebirdSQL/firebird / makeInversion

Method makeInversion

src/jrd/optimizer/Retrieval.cpp:1303–1687  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1301//
1302
1303InversionCandidate* Retrieval::makeInversion(InversionCandidateList& inversions) const
1304{
1305 if (inversions.isEmpty() && !navigationCandidate)
1306 return nullptr;
1307
1308 const double streamCardinality = csb->csb_rpt[stream].csb_cardinality;
1309
1310 // Prepared statements could be optimized against an almost empty table
1311 // and then cached (such as in the restore process), thus causing slowdown
1312 // when the table grows. In this case, let's consider all available indices.
1313 const bool smallTable = (streamCardinality <= THRESHOLD_CARDINALITY);
1314
1315 // These flags work around our smart index selection algorithm. Any explicit
1316 // (i.e. user specified) plan requires all existing indices to be considered
1317 // for a retrieval. Internal (system) requests used by the engine itself are
1318 // often optimized using zero or non-actual statistics, so they are processed
1319 // using somewhat relaxed rules.
1320 const bool customPlan = csb->csb_rpt[stream].csb_plan;
1321 const bool sysRequest = (csb->csb_g_flags & csb_internal);
1322
1323 double totalSelectivity = MAXIMUM_SELECTIVITY; // worst selectivity
1324 double totalIndexCost = 0;
1325
1326 // The upper limit to use an index based retrieval is five indexes + almost all datapages
1327 const double maximumCost = (DEFAULT_INDEX_COST * 5) + (streamCardinality * 0.95);
1328 const double minimumSelectivity = 1 / streamCardinality;
1329
1330 double previousTotalCost = maximumCost;
1331
1332 // Force to always choose at least one index
1333 bool firstCandidate = true;
1334
1335 InversionCandidate* invCandidate = nullptr;
1336
1337 for (auto inversion : inversions)
1338 {
1339 const auto indexScratch = inversion->scratch;
1340
1341 // If the explicit plan doesn't mention this index, fake it as used
1342 // thus excluding it from the cost-based algorithm. Otherwise,
1343 // given this index is suitable for navigation, also mark it as used.
1344
1345 if ((indexScratch &&
1346 (indexScratch->index->idx_runtime_flags & idx_plan_dont_use)) ||
1347 (!customPlan && inversion == navigationCandidate))
1348 {
1349 inversion->used = true;
1350 }
1351 }
1352
1353 MatchedBooleanList matches;
1354
1355 if (navigationCandidate)
1356 {
1357 matches.join(navigationCandidate->matches);
1358
1359 // Reset the selectivity/cost prerequisites to account the navigational candidate
1360 totalSelectivity = navigationCandidate->selectivity;

Callers

nothing calls this directly

Calls 7

InversionCandidateClass · 0.85
isEmptyMethod · 0.45
joinMethod · 0.45
getCountMethod · 0.45
assignMethod · 0.45
existMethod · 0.45
addMethod · 0.45

Tested by

no test coverage detected