Skip to content

Commit eb4b4a3

Browse files
committed
DEV: add query performance tuning page
1 parent c331b85 commit eb4b4a3

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
categories:
3+
- docs
4+
- develop
5+
- stack
6+
- oss
7+
description: Redis Query Engine best practices
8+
linkTitle: Best practices
9+
title: Best practices
10+
weight: 2
11+
---
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
Title: Best practices for Redis Query Engine performance
3+
alwaysopen: false
4+
categories:
5+
- docs
6+
- develop
7+
- stack
8+
- oss
9+
- kubernetes
10+
- clients
11+
linkTitle: RQE performance
12+
weight: 1
13+
---
14+
15+
{{< note >}}
16+
If you're using Redis Software or Redis Cloud, see the [best practices for scalable Redis Query Engine]({{< relref "/operate/oss_and_stack/stack-with-enterprise/search/scalable-query-best-practices" >}}) page.
17+
{{< /note >}}
18+
19+
## Checklist
20+
Below are basic steps to ensure good performance of Redis Query Engine.
21+
22+
* Create a Redis data model with your query patterns in mind.
23+
* Ensure the Redis architecture has been sized for the expected load using the [sizing calculator](https://redis.io/redisearch-sizing-calculator/).
24+
* Provision Redis nodes with sufficient resources (RAM, CPU, network) to support the expected maximum load.
25+
* Review [`FT.INFO`]({{< baseurl >}}/commands/ft.info) and [`FT.PROFILE`]({{< baseurl >}}/commands/ft.profile) outputs for anomalies and/or errors.
26+
* Conduct load testing in a test environment with real-world queries and a load generated by either [memtier_benchmark](https://github.com/redislabs/memtier_benchmark) or a custom load application.
27+
28+
## Indexing considerations
29+
30+
### General
31+
- Favor [`TAG`]({{< relref "/develop/interact/search-and-query/basic-constructs/field-and-type-options#tag-fields" >}}) over [`NUMERIC`]({{< relref "/develop/interact/search-and-query/basic-constructs/field-and-type-options#numeric-fields" >}}) for use cases that only require matching.
32+
- Favor [`TAG`]({{< relref "/develop/interact/search-and-query/basic-constructs/field-and-type-options#tag-fields" >}}) over [`TEXT`]({{< relref "/develop/interact/search-and-query/basic-constructs/field-and-type-options#text-fields" >}}) for use cases that don’t require full-text capabilities (pure match).
33+
34+
### Non-threaded search
35+
- Put only those fields used in your queries in the index.
36+
- Only make fields [`SORTABLE`]({{< relref "/develop/interact/search-and-query/advanced-concepts/sorting" >}}) if they are used in [`SORTBY`]({{< relref "/develop/interact/search-and-query/advanced-concepts/sorting#specifying-sortby" >}})
37+
queries.
38+
- Use [`DIALECT 4`]({{< relref "/develop/interact/search-and-query/advanced-concepts/dialects#dialect-4" >}}).
39+
40+
### Threaded (query performance factor or QPF) search
41+
- Put both query fields and any projected fields (`RETURN` or `LOAD`) in the index.
42+
- Set all fields to `SORTABLE`.
43+
- Set TAG fields to [UNF]({{< relref "/develop/interact/search-and-query/advanced-concepts/sorting#normalization-unf-option" >}}).
44+
- Optional: Set `TEXT` fields to `NOSTEM` if the use case will support it.
45+
- Use [`DIALECT 4`]({{< relref "/develop/interact/search-and-query/advanced-concepts/dialects#dialect-4" >}}).
46+
47+
## Query optimization
48+
49+
- Avoid returning large result sets. Use `CURSOR` or `LIMIT`.
50+
- Avoid wildcard searches.
51+
- Avoid projecting all fields (e.g., `LOAD *`). Project only those fields that are part of the index schema.
52+
- If queries are long-running, enable threading (query performance factor) to reduce contention for the main Redis thread.
53+
54+
## Validate performance (`FT.PROFILE`)
55+
56+
You can analyze [`FT.PROFILE`]({{< baseurl >}}/commands/ft.profile) output to gain insights about query execution.
57+
The following informational items are available for analysis:
58+
59+
- Total execution time
60+
- Execution time per shard
61+
- Coordination time (for multi-sharded environments)
62+
- Breakdown of the query into fundamental components, such as `UNION` and `INTERSECT`
63+
- Warnings, such as `TIMEOUT`
64+
65+
## Anti-patterns
66+
67+
The following items are anti-patterns for RQE:
68+
69+
- Large documents
70+
- Deeply-nested fields
71+
- Large result sets
72+
- Wildcarding
73+
- Large projections
74+
75+
The following examples depict an anti-pattern index schema and query, followed by a corrected index schema and query, which allows for scalability with the Redis Query Engine.
76+
77+
### Anti-pattern index schema
78+
79+
The following index schema is not optimized for vertical scaling:
80+
81+
```sh
82+
FT.CREATE jsonidx:profiles ON JSON PREFIX 1 profiles:
83+
SCHEMA $.tags.* as t NUMERIC SORTABLE
84+
$.firstName as name TEXT
85+
$.location as loc GEO
86+
```
87+
88+
### Anti-pattern query
89+
90+
The following query is not optimized for vertical scaling:
91+
92+
```sh
93+
FT.AGGREGATE jsonidx:profiles '@t:[1299 1299]' LOAD * LIMIT 0 10
94+
```
95+
96+
### Improved index schema
97+
98+
Here's an improved index schema that follows best practices for vertical scaling:
99+
100+
```sh
101+
FT.CREATE jsonidx:profiles ON JSON PREFIX 1 profiles:
102+
SCHEMA $.tags.* as t NUMERIC SORTABLE
103+
$.firstName as name TEXT NOSTEM SORTABLE
104+
$.lastName as lastname TEXT NOSTEM SORTABLE
105+
$.location as loc GEO SORTABLE
106+
$.id as id TAG SORTABLE UNF
107+
$.ver as ver TAG SORTABLE UNF
108+
```
109+
110+
### Improved query
111+
112+
Here's an improved query that follows best practices for vertical scaling:
113+
114+
```sh
115+
FT.AGGREGATE jsonidx:profiles '@t:[1299 1299]'
116+
LOAD 6 id t nam" lastname loc ver
117+
LIMIT 0 10
118+
DIALECT 3
119+
```

0 commit comments

Comments
 (0)