From 6a9eb2e355dee728d6fdbc198bcc61310f880612 Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Sat, 20 Jan 2024 20:43:27 -0800 Subject: [PATCH] Do not use index if large % of tuples will be filtered unless unless enable_seqscan = off --- src/hnsw.c | 28 ++++++++++++++++++++++++++++ test/t/018_hnsw_filtering.pl | 7 ++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/hnsw.c b/src/hnsw.c index 1719820..9da497d 100644 --- a/src/hnsw.c +++ b/src/hnsw.c @@ -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); diff --git a/test/t/018_hnsw_filtering.pl b/test/t/018_hnsw_filtering.pl index 058009c..64864e4 100644 --- a/test/t/018_hnsw_filtering.pl +++ b/test/t/018_hnsw_filtering.pl @@ -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