# Indexes Database indexes are essential for performance. In particular you will need indexes to speed up search requests. Aidbox provides mechanisms to * manage indexes * suggest indexes * generate indexes automatically ## Background Aidbox uses [PostgreSQL](https://www.postgresql.org/) database for storage. Most of resource data is contained in [_resource_](../../database/database-schema.md) column with [_jsonb_](https://www.postgresql.org/docs/current/datatype-json.html) type. Consider simple example: _active_ search parameter for _Patient_ resource. Let's try the search query ```http GET /Patient?active=true ``` Use [\_explain](../../api/rest-api/aidbox-search.md#explain) to find out SQL query generated by this request ``` GET /Patient?active=true&_explain=analyze ``` Possible response is ``` query: - >- SELECT "patient".* FROM "patient" WHERE "patient".resource @> ? LIMIT ? OFFSET ? - '{"active":true}' - 100 - 0 plan: >- Limit (cost=0.00..1.01 rows=1 width=124) (actual time=0.015..0.015 rows=0 loops=1) -> Seq Scan on patient (cost=0.00..1.01 rows=1 width=124) (actual time=0.014..0.014 rows=0 loops=1) Filter: (resource @> '{"active": true}'::jsonb) Rows Removed by Filter: 1 Planning Time: 0.729 ms Execution Time: 0.050 ms ``` Corresponding SQL is ```sql SELECT "patient".* FROM "patient" WHERE "patient".resource @> '{"active": "true"}'::jsonb LIMIT 100 OFFSET 0 ``` Here [`@>`](https://www.postgresql.org/docs/current/functions-json.html) is containment operator. It tests whether _jsonb_ value on the right-hand side is contained in the _jsonb_ value on the left-hand side. Without indexes Postgres has to check this condition for every _Patient_ resource stored in the database. However, [_GIN indexes_](https://www.postgresql.org/docs/current/datatype-json.html#JSON-INDEXING) can speed up these kind of queries. We can create GIN index for the `resource` column ```sql CREATE INDEX patient_resource_gin_idx ON Patient USING GIN (resource) ``` Now Postgres can use this index to make search much faster. ### Functional indexes Consider more complex example: `name` search parameter for `Patient` resource. Request ``` GET /Patient?name=abc ``` Generates SQL like
SELECT *
FROM Patient
WHERE
aidbox_text_search(
knife_extract_text(
resource,
'[["name","family"],["name","given"],["name","middle"],["name","text"]]'
)
) ILIKE unaccent('% abc%')
LIMIT 100
OFFSET 0
Postgres' [`pg_trgm` module](https://www.postgresql.org/docs/current/pgtrgm.html#id-1.11.7.44.8) supports index searches for `ILIKE` queries.
You can create functional index to speed up this query:
```sql
CREATE INDEX patient_name_trgm_idx
ON Patient
USING GIN (
aidbox_text_search(
knife_extract_text(
resource,
'[["name","family"],["name","given"],["name","middle"],["name","text"]]'
)
) gin_trgm_ops
)
```
## Index suggestion
Aidbox provides two RPCs that can suggest you indexes
### Suggest indexes for parameter
Use `aidbox.index/suggest-index` RPC to get index suggestion for specific search parameter
```
POST /rpc
Content-Type: text/yaml
Accept: text/yaml
method: aidbox.index/suggest-index
params:
resource-type: