# Vespa Search Performance Tuning

This document describes how to tune your application for high performance while search sizing guide discuss how to scale your application.

## Document Model Schema and Performance

### Attribute v.s index

The attribute documentation summaries when to use attribute in the indexing statement. Adding attribute:fast-search will speed up searches over attribute fields by building an in-memory index over the values in the attribute field.

field timestamp type long {
indexing: summary | attribute
attribute:fast-search
rank:filter
}


If you configure both index and attribute for string type fields Vespa will do search and matching against the index with default match text.

### Indexing strings in Vespa: Matching and Performance

When configuring string type fields with index the default match mode is text which means Vespa will tokenize the content and index the tokens. An example document definition is provided below where there are 3 fields; two fields of type string and one double field.

search foo {
document foo {
field title type string {
indexing:summary | index
}
field uuid type string {
indexing:summary | index
}
field popularity type double {
indexing: summary | attribute
}
}
}


The string representation of an Universally unique identifiel (UUID) is represented as 32 hexadecimal (base 16) digits, displayed in five groups separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters (32 alphanumeric characters and four hyphens). An example string representation of an UUID is 123e4567-e89b-12d3-a456-426655440000.
When indexed with the above document definition Vespa will tokenize 123e4567-e89b-12d3-a456-426655440000 into 5 tokens [123e4567,e89b,12d3,a456,426655440000].
When querying Vespa for the same UUID /search/?query=uuid:123e4567-e89b-12d3-a456-426655440000 Vespa will because of the hyphens treat the input as an implicit phrase query uuid:"123e4567 e89b12d3 a456 426655440000" which has a signifcant higher cost compared with searching for a single word term as phrase search is evaluated over positional indicies. We can let Vespa know that we don't want any tokenization by changing the match mode to word. This change will avoid tokenization of the field and will store the entire input 123e4567-e89b-12d3-a456-426655440000 as one token and avoid implicit phrase search triggering.

    field uuid type string {
indexing:summary | index
match:word
rank:filter
}


This tells Vespa that the uuid field of type string should be treated as a rank:filter field, this is a hint to Vespa that this string field should be represented as efficient as possible during search and ranking. Please make sure to review all string fields in your application and ask yourself if you need tokenized matching or not and if the field should be used for ranking or not. The rank:filter behavior can also be triggered at query time on a per query item basis by the com.yahoo.prelude.query.Item.setRanked() in a custom searcher working on the parsed query tree.

### Parent child relationships and Search Performance

When searching imported attribute fields from parent document types there is an additional cost penalty which can be reduced significantly if the imported field is defined with rank:filter and visibility-delay is configured to > 0.

## Ranking & Performance

Generally Vespa scales with the number of hits the query recalls which needs to be ranked per node. The ranking cost per document recalled is determined by the complexity of the ranking expression in use and the rank feature complexity.

## Summary Performance

If your use case is requesting many hits from a few content nodes adding a summary cache will reduce cost. If your application can afford the additional memory footprint it's possible to configure explicit document summaries which could be used to fetch summaries only from memory by only referencing fields which have attribute in their indexing statement. If you believe you are bound by summary performance you can test using the internal reserved document summary which contains all single-valued attribute fields by benchmarking with &summary=attributeprefetch which will avoid disk access entirely.