Check out v4 of the Fauna CLI
v4 of the Fauna CLI is now in beta. The new version introduces enhancements to the developer experience, including an improved authentication workflow. To get started, check out the CLI v4 quick start. |
Query best practices
This guide covers best practices for querying data in Fauna.
Use indexes for commonly accessed data
Indexes are the most important and effective tool to increase performance and reduce the cost of your queries.
Avoid uncovered queries whenever possible. To reduce document reads, include any frequently queried fields in indexes.
See Indexes |
---|
Use index terms for exact match searches
For the best performance, especially on large datasets, use an index with terms to filter collection documents based on an exact field value.
collection.where()
and
collection.firstWhere()
require a scan of the entire collection and aren’t performant on large
collections.
Avoid using frequently updated fields as index terms. See Avoid using frequently updated fields as index terms.
See Index terms |
---|
Avoid using frequently updated fields as index terms
Internally, Fauna partitions indexes based on its terms, if present. Frequent updates to term field values trigger updates to these partitions.
If you need to filter or run an exact match search on a frequently updated field, consider adding the field as an index value instead:
collection Product {
...
// Defines the `sortedByName()` index.
// The index includes the `name` field as an index value.
// `name` is a frequently updated field.
index sortedByName {
values [.name, .description, .price]
}
}
Then use the index to run a range search on the index value:
// Uses the `sortedByName()` index to run a range search
// on `name` field values. The query only retrieves `Product`
// collection documents with a `name` of `limes`. The query
// is covered and avoids document reads.
Product.sortedByName({ from: "limes", to: "limes" }) {
name,
description,
price
}
Use index values for sorting and range searches
For large collections, use index values instead of
set.order()
to sort a collection’s
documents. Reserve set.order()
for
small, ad-hoc sorting on Sets of one page or less.
Similarly, avoid using
collection.where()
to
perform range searches on large collections. Instead, run a range search on
index values.
See Index values |
---|
Use projection to only retrieve fields you need
Projection lets you select the fields to return from a document or Set.
For the best performance and costs, use an index and only project fields covered as an index term or value. This lets you read data from the index rather than the underlying documents.
To reduce unneeded compute operations, use projection to only fetch computed fields when needed. Computed fields aren’t persistently stored as part of the document. Instead, the field’s value is computed on each read.
See Projection and field aliasing |
---|
Return null
on document writes
Methods that create or write to a document, such as
Collection.create()
or
document.update()
, typically
return the document.
An FQL query only returns the result of its last statement. If you don’t use the
returned document, you can add a null
statement to the end of the query to
return null
instead. This can lower egress costs.
For example:
// The `update()` call writes to a `Product` collection document.
// `update()` returns the updated document.
Product.byId("111")
?.update({ price: 75 })
// FQL queries return the result of the last statement.
// The `null` statement ensures the query returns `null`.
null
Use pageSize()
for pagination
In most cases, you should use
set.pageSize()
, not
set.paginate()
, to control the
page size of paginated results. Unlike pageSize()
, paginate()
:
-
Uses eager loading and fetches results instantly, even if the results aren’t returned or used. This can produce slower and more wasteful queries.
-
Is not compatible with Fauna client driver pagination methods.
See Pagination |
---|
Create UDFs for complex queries and workflows
A user-defined function (UDF) is a Set of one or more FQL statements stored as a reusable resource in a Fauna database.
UDFs are composable, letting you combine multiple UDFs to create more complex functions or workflows.
In most cases, a query that’s rewritten in multiple places or that involves complex logic should be stored as a UDF.
See User-defined functions (UDFs) |
---|
Use Fauna Logs to monitor query performance
You can use Fauna Logs to monitor the performance of your Fauna queries and diagnose issues.
Instrument your queries with query tags and traceparent identifiers. You can then aggregate the logs to identify trends or visualize the logs in an observability platform, such as Datadog.
See Fauna Logs |
---|
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!