mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-02-02 09:20:39 +01:00
Better selectivity assumption for compound indices on empty tables
This commit is contained in:
parent
b3c54800f3
commit
29b269b129
@ -898,6 +898,17 @@ void Retrieval::getInversionCandidates(InversionCandidateList& inversions,
|
|||||||
// Add matches for this segment to the main matches list
|
// Add matches for this segment to the main matches list
|
||||||
matches.join(segment.matches);
|
matches.join(segment.matches);
|
||||||
|
|
||||||
|
// When selectivity is zero the statement is prepared on an
|
||||||
|
// empty table or the statistics aren't updated.
|
||||||
|
// For an unique index, estimate the selectivity via the stream cardinality.
|
||||||
|
// For a non-unique one, assume 1/10 of the maximum selectivity, so that
|
||||||
|
// at least some indexes could be chosen by the optimizer.
|
||||||
|
if (scratch.selectivity <= 0)
|
||||||
|
{
|
||||||
|
scratch.selectivity = (unique && cardinality > MINIMUM_CARDINALITY) ?
|
||||||
|
1 / cardinality : DEFAULT_SELECTIVITY;
|
||||||
|
}
|
||||||
|
|
||||||
// An equality scan for any unique index cannot retrieve more
|
// An equality scan for any unique index cannot retrieve more
|
||||||
// than one row. The same is true for an equivalence scan for
|
// than one row. The same is true for an equivalence scan for
|
||||||
// any primary index.
|
// any primary index.
|
||||||
@ -988,16 +999,8 @@ void Retrieval::getInversionCandidates(InversionCandidateList& inversions,
|
|||||||
|
|
||||||
if (scratch.scopeCandidate)
|
if (scratch.scopeCandidate)
|
||||||
{
|
{
|
||||||
// When selectivity is zero the statement is prepared on an
|
|
||||||
// empty table or the statistics aren't updated.
|
|
||||||
// For an unique index, estimate the selectivity via the stream cardinality.
|
|
||||||
// For a non-unique one, assume 1/10 of the maximum selectivity, so that
|
|
||||||
// at least some indexes could be chosen by the optimizer.
|
|
||||||
double selectivity = scratch.selectivity;
|
double selectivity = scratch.selectivity;
|
||||||
|
|
||||||
if (selectivity <= 0)
|
|
||||||
selectivity = unique ? 1 / cardinality : DEFAULT_SELECTIVITY;
|
|
||||||
|
|
||||||
// Calculate the cost (only index pages) for this index
|
// Calculate the cost (only index pages) for this index
|
||||||
auto cost = DEFAULT_INDEX_COST + selectivity * scratch.cardinality;
|
auto cost = DEFAULT_INDEX_COST + selectivity * scratch.cardinality;
|
||||||
|
|
||||||
@ -1007,8 +1010,7 @@ void Retrieval::getInversionCandidates(InversionCandidateList& inversions,
|
|||||||
selectivity *= listCount;
|
selectivity *= listCount;
|
||||||
selectivity = MIN(selectivity, maxSelectivity);
|
selectivity = MIN(selectivity, maxSelectivity);
|
||||||
|
|
||||||
const auto rootScanCost = DEFAULT_INDEX_COST * listCount +
|
const auto rootScanCost = cost * listCount;
|
||||||
scratch.cardinality * selectivity;
|
|
||||||
const auto siblingScanCost = DEFAULT_INDEX_COST +
|
const auto siblingScanCost = DEFAULT_INDEX_COST +
|
||||||
scratch.cardinality * maxSelectivity * (listCount - 1) / (listCount + 1);
|
scratch.cardinality * maxSelectivity * (listCount - 1) / (listCount + 1);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user