Do not use index if large % of tuples will be filtered unless unless enable_seqscan = off

This commit is contained in:
Andrew Kane
2024-01-20 20:43:27 -08:00
parent 490522b883
commit 6a9eb2e355
2 changed files with 34 additions and 1 deletions

View File

@@ -94,6 +94,34 @@ hnswcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
return;
}
/*
* Do not use index if large % of tuples will be filtered unless
* enable_seqscan = off
*/
if (list_length(path->indexinfo->indrestrictinfo) > 0)
{
double selectivity = 1;
ListCell *lc;
foreach(lc, path->indexinfo->indrestrictinfo)
{
RestrictInfo *rinfo = lfirst(lc);
if (rinfo->norm_selec >= 0 && rinfo->norm_selec <= 1)
selectivity *= rinfo->norm_selec;
}
if (selectivity < 0.1)
{
*indexStartupCost = 1.0e10 - 1;
*indexTotalCost = 1.0e10 - 1;
*indexSelectivity = 0;
*indexCorrelation = 0;
*indexPages = 0;
return;
}
}
MemSet(&costs, 0, sizeof(costs));
index = index_open(path->indexinfo->indexoid, NoLock);

View File

@@ -36,7 +36,12 @@ my $c = int(rand() * $nc);
my $explain = $node->safe_psql("postgres", qq(
EXPLAIN ANALYZE SELECT i FROM tst WHERE c = $c ORDER BY v <-> '$query' LIMIT $limit;
));
# TODO Do not use index
like($explain, qr/Seq Scan/);
# Test attribute filtering with few rows removed
$explain = $node->safe_psql("postgres", qq(
EXPLAIN ANALYZE SELECT i FROM tst WHERE c != $c ORDER BY v <-> '$query' LIMIT $limit;
));
like($explain, qr/Index Scan using idx/);
# Test distance filtering