forked from apache/cassandra
-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CNDB-10629 Faster SAI predicate selectivity estimation #1253
Open
pkolaczk
wants to merge
1
commit into
main
Choose a base branch
from
10629-sai-stats
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pkolaczk
changed the title
10629 sai stats
CNDB-10629 Faster SAI predicate selectivity estimation
Aug 29, 2024
pkolaczk
force-pushed
the
10629-sai-stats
branch
3 times, most recently
from
August 29, 2024 16:02
443ba9e
to
d592fb2
Compare
pkolaczk
force-pushed
the
10629-sai-stats
branch
3 times, most recently
from
September 17, 2024 07:58
5f146f1
to
aa61fdf
Compare
Fixes riptano/cndb#10629 This commit introduces a new system for estimation of predicate selectivities used by the SAI query planner. So far the SAI planner had to perform search on each index referenced by the query in order to learn the expected number of rows matched by each predicate. That required hitting each sstable index, going down the KD-tree/trie, and collecting/merging the posting lists. Even though the posting lists didn't have to be iterated fully, in some cases the cost of obtaining the posting lists could be significant. That effort could be wasted if the planner decided to not include the index in the final plan. This new feature adds extended statistical information to the SegmentMetadata. When building index segments, a histogram and a table of most frequent terms are built and saved with the segment metadata. Then that information is used to estimate the number of matching rows by each query predicate at the query planning stage. Because histograms are tiny and all kept in memory, this is orders of magnitude faster than searching the index. Summary of the code changes introduced by this commit: * Introduced `TermsDistribution` class that records histograms / most frequent terms in memory and quickly estimates the number of rows matched by predicates. * Introduced `SegmentMetadataBuilder` class responsible for building `SegmentMetadata`s with `TermsDistribution`s. This class provides interceptors that plug into the index building process and allow it to intercept additions to the index in an ordered way. * Introduced a new version of the `OnDiskFormat` of SAI indexes: "EA". Unfortunately adding new segment metadata could not be performed in a forward-compatible way because `SegmentMetadata` did not store any length fields in the serialization. If any of the indexes is on the older version, the whole estimation will be done the old way, by performing search. * Memory indexes got new methods for estimation of row counts. Estimation can be performed faster than running the search. * `QueryController` was reorganized to use the new / old system of estimation, depending on the index version. * `QueryView` has been refactored and made more flexible. Query view builder is now an inner class, following the pattern we use in many other places. It doesn't need an explicit reference to `Orderer` now, but takes a more generic `IndexContext`. * `QueryController` now uses `QueryView` / `QueryView.Builder` to lock references to indexes for all types of queries (earlier it used QueryView for vector search and similar duplicated logic inline for non-vector search) - overall a lot of code removed / simplified there. * TermsIterator is now responsible for both increasing and decreasing the reference counts on the referenced iterators. This allows sharing the same `QueryView` between multiple iterators. `QueryView#referencedIndexes` and `referencedMemtables` collections are now immutable. Limitations: * Memory indexes do not use histograms at the moment. For point lookups, search is performed the old way, because this is usually very fast anyway. For range queries, we perform search only partially and estimate the total number of matches by extrapolation. * Prefiltering the set of indexes selected for intersections got removed from `QueryController`. This optimization was complex and looked misplaced. If performance testing shows the removal of it caused a performance regression, it should be reintroduced in the planner.
pkolaczk
force-pushed
the
10629-sai-stats
branch
from
September 18, 2024 15:14
74d7428
to
9fea046
Compare
Quality Gate passedIssues Measures |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
CNDB-10629: Estimate predicate selectivity using histograms
Fixes https://github.com/riptano/cndb/issues/10629
This commit introduces a new system for estimation of predicate
selectivities used by the SAI query planner.
So far the SAI planner had to perform search on each index referenced
by the query in order to learn the expected number of rows matched
by each predicate. That required hitting each sstable index,
going down the KD-tree/trie, and collecting/merging the posting lists.
Even though the posting lists didn't have to be iterated fully, in
some cases the cost of obtaining the posting lists could be
significant. That effort could be wasted if the planner decided
to not include the index in the final plan.
This new feature adds extended statistical information to the
SegmentMetadata. When building index segments, a histogram and
a table of most frequent terms are built and saved with the segment
metadata. Then that information is used to estimate the number
of matching rows by each query predicate at the query planning stage.
Because histograms are tiny and all kept in memory, this is orders
of magnitude faster than searching the index.
Summary of the code changes introduced by this commit:
Introduced
TermsDistribution
class that records histograms / mostfrequent terms in memory and quickly estimates the number of rows
matched by predicates.
Introduced
SegmentMetadataBuilder
class responsible for buildingSegmentMetadata
s withTermsDistribution
s. This class providesinterceptors that plug into the index building process and allow
it to intercept additions to the index in an ordered way.
Introduced a new version of the
OnDiskFormat
of SAI indexes: "EA".Unfortunately adding new segment metadata could not be performed in
a forward-compatible way because
SegmentMetadata
did not storeany length fields in the serialization. If any of the indexes
is on the older version, the whole estimation will be done the old
way, by performing search.
Memory indexes got new methods for estimation of row counts.
Estimation can be performed faster than running the search.
QueryController
was reorganized to use the new / old systemof estimation, depending on the index version.
QueryView
has been refactored and made more flexible.Query view builder is now an inner class,
following the pattern we use in many other places.
It doesn't need an explicit reference to
Orderer
now, but takesa more generic
IndexContext
.QueryController
now usesQueryView
/QueryView.Builder
to lockreferences to indexes for all types of queries (earlier it used
QueryView for vector search and similar duplicated logic inline for
non-vector search) - overall a lot of code removed / simplified
there.
TermsIterator is now responsible for both increasing and decreasing
the reference counts on the referenced iterators. This allows
sharing the same
QueryView
between multiple iterators.QueryView#referencedIndexes
andreferencedMemtables
collectionsare now immutable.
Limitations:
Memory indexes do not use histograms at the moment.
For point lookups, search is performed the old way, because
this is usually very fast anyway. For range queries, we perform
search only partially and estimate the total number of matches by
extrapolation.
Prefiltering the set of indexes selected for intersections
got removed from
QueryController
.This optimization was complex and looked misplaced.
If performance testing shows the removal of it caused a performance
regression, it should be reintroduced in the planner.