You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/en/engines/table-engines/mergetree-family/annindexes.md
+45-33Lines changed: 45 additions & 33 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -78,7 +78,7 @@ ClickHouse provides a special "vector similarity" index to perform approximate n
78
78
:::note
79
79
Vector similarity indexes are currently experimental.
80
80
To enable them, please first run `SET allow_experimental_vector_similarity_index = 1`.
81
-
If you run into problems, kindly open an issue at github.com/clickhouse/clickhouse/issues.
81
+
If you run into problems, kindly open an issue in the [ClickHouse repository](github.com/clickhouse/clickhouse/issues).
82
82
:::
83
83
84
84
### Creating a Vector Similarity Index {#creating-a-vector-similarity-index}
@@ -174,13 +174,13 @@ LIMIT <N>
174
174
ClickHouse's query optimizer tries to match above query template and make use of available vector similarity indexes.
175
175
A query can only use a vector similarity index if the distance function in the SELECT query is the same as the distance function in the index definition.
176
176
177
-
Advanced users may provide a custom value for setting [hnsw_candidate_list_size_for_search](../../../operations/settings/settings.md#hnsw_candidate_list_size_for_search) (also know as HNSW hyperparameter `ef_search`) to tune the size of the candidate list during search (e.g. `SELECT [...] SETTINGS hnsw_candidate_list_size_for_search = <value>`).
177
+
Advanced users may provide a custom value for setting [hnsw_candidate_list_size_for_search](../../../operations/settings/settings.md#hnsw_candidate_list_size_for_search) (also know as HNSW hyperparameter "ef_search") to tune the size of the candidate list during search (e.g. `SELECT [...] SETTINGS hnsw_candidate_list_size_for_search = <value>`).
178
178
The default value of the setting 256 works well in the majority of use cases.
179
179
Higher setting values mean better accuracy at the cost of slower performance.
180
180
181
181
If the query can use a vector similarity index, ClickHouse checks that the LIMIT `<N>` provided in SELECT queries is within reasonable bounds.
182
182
More specifically, an error is returned if `<N>` is bigger than the value of setting [max_limit_for_vector_search_queries](../../../operations/settings/settings.md#max_limit_for_vector_search_queries) with default value 100.
183
-
Too large LIMITs can slow down searches and usually indicate a usage error.
183
+
Too large LIMIT values can slow down searches and usually indicate a usage error.
184
184
185
185
To check if a SELECT query uses a vector similarity index, you can prefix the query with `EXPLAIN indexes = 1`.
186
186
@@ -231,21 +231,22 @@ To enforce index usage, you can run the SELECT query with setting [force_data_sk
231
231
232
232
**Post-filtering and Pre-filtering**
233
233
234
-
Users may optionally specify a `WHERE` clause with additional filter conditions in SELECT queries.
235
-
Depending on these filter conditions, ClickHouse will utilize post-filtering or pre-filtering.
236
-
These two strategies determine the order in which the filters are evaluated:
237
-
-With post-filtering, the vector similarity index is evaluated first, afterwards ClickHouse evaluates the additional filter(s) specified of the `WHERE` clause.
238
-
-With pre-filtering, the filter evaluation order is the other way round.
234
+
Users may optionally specify a `WHERE` clause with additional filter conditions for the SELECT query.
235
+
ClickHouse will evaluate these filter conditions using post-filtering or pre-filtering strategy.
236
+
In short, both strategies determine the order in which the filters are evaluated:
237
+
-Post-filtering means that the vector similarity index is evaluated first, afterwards ClickHouse evaluates the additional filter(s) specified in the `WHERE` clause.
238
+
-Pre-filtering means that the filter evaluation order is the other way round.
239
239
240
-
Both strategies have different trade-offs:
241
-
- Post-filtering has the general problem that it may return less than the number of rows requested in the `LIMIT <N>` clause. This situation happens when at least one of the result rows returned by the vector similarity index fails to satisfy the additional filters.
242
-
- Pre-filtering is generally an unsolved problem. Some specialized vector databases implement it but most databases including ClickHouse will fall back to exact neighbor search, i.e., a brute-force scan without index.
240
+
The strategies have different trade-offs:
241
+
- Post-filtering has the general problem that it may return less than the number of rows requested in the `LIMIT <N>` clause. This situation happens when one or more result rows returned by the vector similarity index fails to satisfy the additional filters.
242
+
- Pre-filtering is generally an unsolved problem. Certain specialized vector databases provide pre-filtering algorithms but most relational databases (including ClickHouse) will fall back to exact neighbor search, i.e., a brute-force scan without index.
243
243
244
-
What strategy is used comes down to whether ClickHouse can use indexes for the additional filter conditions.
245
-
If no index can be used, post-filtering will be applied.
244
+
What strategy is used depends on the filter condition.
245
+
246
+
*Additional filters are part of the partition key*
246
247
247
248
If the additional filter condition is part of the partition key, then ClickHouse will apply partition pruning.
248
-
For example, assuming that the table is range-partitioned by `year`:
249
+
As an example, a table is range-partitioned by column `year` and the following query is run:
249
250
250
251
```sql
251
252
WITH [0., 2.] AS reference_vec
@@ -256,20 +257,30 @@ ORDER BY L2Distance(vec, reference_vec) ASC
256
257
LIMIT3;
257
258
```
258
259
259
-
ClickHouse will ignore all partitions but the one for year 2025.
260
-
Within this partition, a post-filtering strategy will be applied.
260
+
ClickHouse will prune all partitions except the 2025 one.
261
+
262
+
*Additional filters cannot be evaluated using indexes*
263
+
264
+
If additional filter conditions cannot be evaluated using indexes (primary key index, skipping index), ClickHouse will apply post-filtering.
265
+
266
+
*Additional filters can be evaluated using the primary key index*
261
267
262
-
If the additional filter condition is on the primary key columns and the filter selects some but not all ranges of a part, then Clickhouse will fall back to exact neighbour search (brute-force scan without index) on the selected ranges of the part.
263
-
If the primary key filter selects entire parts, Clickhouse will use the vector similarity index on those parts to retrieve results.
268
+
If additional filter conditions can be evaluated using the [primary key](mergetree.md#primary-key) (i.e., they form a prefix of the primary key) and
269
+
- the filter condition eliminates at least one row within a part, the ClickHouse will fall back to pre-filtering for the "surviving" ranges within the part,
270
+
- the filter condition eliminates no rows within a part, the ClickHouse will perform post-filtering for the part.
264
271
265
-
In case additional filter conditions on columns can make use of skip indexes (minmax, set etc), Clickhouse by default chooses a post-filtering strategy.
266
-
Clickhouse gives higher priority to the vector similarity index because the vector index is expected to deliver business value by accelerating semantic search response times.
272
+
In practical use cases, the latter case is rather unlikely.
267
273
268
-
Clickhouse provides 2 settings for finer control on post-filtering and pre-filtering:
274
+
*Additional filters can be evaluated using skipping index*
269
275
270
-
When the additional filter conditions are extremely selective, it is possible that brute force search on a small filtered set of rows gives better results then post-filtering using the vector search.
271
-
Users can force pre-filtering by setting [vector_search_filter_strategy](../../../operations/settings/settings#vector_search_filter_strategy) to `prefilter` (default is `auto` which is equivalent to `postfilter`).
272
-
An example query where pre-filtering could be a good choice is
276
+
If additional filter conditions can be evaluated using [skipping indexes](mergetree.md#table_engine-mergetree-data_skipping-indexes) (minmax index, set index, etc.), Clickhouse performs post-filtering.
277
+
In such cases, the vector similarity index is evaluated first as it is expected to remove the most rows relative to other skipping indexes.
278
+
279
+
For finer control over post-filtering vs. pre-filtering, two settings can be used:
280
+
281
+
Setting [vector_search_filter_strategy](../../../operations/settings/settings#vector_search_filter_strategy) (default: `auto` which implements above heuristics) may be set to `prefilter`.
282
+
This is useful to force pre-filtering in cases where the additional filter conditions are extremely selective.
283
+
As an example, the following query may benefit from pre-filtering:
273
284
274
285
```sql
275
286
SELECT bookid, author, title
@@ -279,24 +290,25 @@ ORDER BY cosineDistance(book_vector, getEmbedding('Books on ancient Asian empire
279
290
LIMIT10
280
291
```
281
292
282
-
Assuming that only very few books cost less than $2, post-filtering may return zero rows because the top 10 matches returned by the vector index could all be priced above $2.
283
-
By forcing pre-filtering (add `SETTINGS vector_search_filter_strategy = 'prefilter'` to the query), ClickHouse first finds all books with a price of less than $2 and then executes a brute-force vector search on the matches.
293
+
Assuming that only a very small number of books cost less than $2, post-filtering may return zero rows because the top 10 matches returned by the vector index could all be priced above $2.
294
+
By forcing pre-filtering (add `SETTINGS vector_search_filter_strategy = 'prefilter'` to the query), ClickHouse first finds all books with a price of less than $2 and then executes a brute-force vector search for the found books.
284
295
285
-
As mentioned above, post-filtering may return less matches then specified in the `LIMIT <N>` clause.
286
-
Consider query
296
+
As an alternative approach to resolve above issue, setting [vector_search_postfilter_multiplier](../../../operations/settings/settings#vector_search_postfilter_multiplier) (default: `1.0`) may be configured to a value > `1.0` (for example, `2.0`).
297
+
The number of nearest neighbors fetched from the vector index is multiplied by the setting value and then the additional filter to be applied on those rows to return LIMIT-many rows.
298
+
As an example, we can query again but with multiplier `3.0`:
287
299
288
300
```sql
289
301
SELECT bookid, author, title
290
302
FROM books
291
-
WHEREpublished_year <=2000
303
+
WHEREprice <2.00
292
304
ORDER BY cosineDistance(book_vector, getEmbedding('Books on ancient Asian empires'))
293
305
LIMIT10
306
+
SETTING vector_search_postfilter_multiplier =3.0;
294
307
```
295
308
296
-
With post-filtering, some of the 10 nearest matching books returned by the vector index may be pruned from the result because they were published later than in the year 2000.
297
-
As a result, the query may return less rows than the user requested.
298
-
For such cases, you can set parameter [vector_search_postfilter_multiplier](../../../operations/settings/settings#vector_search_postfilter_multiplier) to a value > 1.0 (for example, 2.0) to indicate that N times this factor many matches should be returned by the vector index and then the additional filter to be applied on those rows to return the result of 10 rows.
299
-
We note that this method can mitigate the problem with post-filtering but in extreme cases (extremely selective WHERE condition), there may still less than N requested rows returned.
309
+
ClickHouse will fetch 3.0 x 10 = 30 nearest neighbors from the vector index in each part and afterwards evaluate the additional filters.
310
+
Only the ten closest neighbors will be returned.
311
+
We note that setting `vector_search_postfilter_multiplier` can mitigate the problem but in extreme cases (very selective WHERE condition), it is still possible that less than N requested rows returned.
If a vector search query has a WHERE clause, this setting determines if it is evaluated first (pre-filtering) OR if the vector similarity index is checked first (post-filtering).
6591
-
6592
-
Possible values:
6593
-
6594
-
'auto' - Postfiltering (the exact semantics may change in future).
6595
-
'postfilter' - Use vector similarity index to identify the nearest neighbours, then apply other filters
6596
-
'prefilter' - Evaluate other filters first, then perform brute-force search to identify neighbours.
6587
+
If a vector search query has a WHERE clause, this setting determines if it is evaluated first (pre-filtering) OR if the vector similarity index is checked first (post-filtering). Possible values:
6588
+
- 'auto' - Postfiltering (the exact semantics may change in future).
6589
+
- 'postfilter' - Use vector similarity index to identify the nearest neighbours, then apply other filters
6590
+
- 'prefilter' - Evaluate other filters first, then perform brute-force search to identify neighbours.
0 commit comments