Query optimization hints for ScyllaDB.
Provides:
- Per-query consistency level overrides
- Query-level timeouts
- Paging hints for large result sets
- Token range optimization for partition-aware queries
- Speculative retry policy configuration
- Query profiling helpers
Usage
# Build an optimized query
query = AshScylla.DataLayer.QueryOptimizer.optimize(query, [
consistency: :one,
timeout: 5_000,
page_size: 100,
speculative_retry: :99percentile
])
Summary
Functions
Analyzes a query and returns optimization suggestions.
Estimates query cost based on filters, sorts, and limit.
Determines the optimal page size for a query based on result set estimation.
Applies optimization hints to a DataLayer query struct.
Wraps a query with profiling enabled.
Returns recommended consistency level based on query type.
Generates CQL for speculative retry policy at session level.
Generates CQL query options for Xandra execution.
Generates a token-aware routing hint for the query.
Generates a token range query for partition-aware scanning.
Functions
@spec analyze(AshScylla.DataLayer.t()) :: [String.t()]
Analyzes a query and returns optimization suggestions.
Returns a list of suggestion strings like:
- "Consider adding secondary index on :email for faster lookups"
- "Query performs full table scan - add partition key filter"
- "Use token-based pagination for large result sets"
@spec estimate_cost(AshScylla.DataLayer.t()) :: atom()
Estimates query cost based on filters, sorts, and limit.
Returns :low, :medium, :high, or :full_scan.
@spec optimal_page_size(AshScylla.DataLayer.t()) :: non_neg_integer()
Determines the optimal page size for a query based on result set estimation.
Uses heuristics based on:
- Whether the query has a partition key filter (small page)
- Whether the query is a full table scan (large page)
- The number of clustering columns
@spec optimize( AshScylla.DataLayer.t(), keyword() ) :: keyword()
Applies optimization hints to a DataLayer query struct.
Returns a keyword list of Xandra execution options that can be merged
into the repo.query/3 call.
Options
:consistency- Override consistency level for this query:timeout- Query timeout in milliseconds:page_size- Number of rows per page for token-based pagination:speculative_retry- Speculative retry policy (:none,:"99percentile",:custom):speculative_retry_delay_ms- Custom delay for speculative retry (ms):serial_consistency- Serial consistency for LWT (:serial,:local_serial):profiling- Enable query profiling (default: false):allow_filtering- Allow filtering (default: false, not recommended)
Wraps a query with profiling enabled.
ScyllaDB supports the PROFILE prefix for query profiling. This returns the query wrapped for profiling.
Examples
iex> AshScylla.DataLayer.QueryOptimizer.profile_query("SELECT * FROM users")
"PROFILE SELECT * FROM users"
Returns recommended consistency level based on query type.
- Read-heavy, low-latency:
:one - Balanced:
:local_quorum - Strong consistency:
:quorum - Critical writes:
:all
@spec speculative_retry_cql(atom(), non_neg_integer() | nil) :: String.t()
Generates CQL for speculative retry policy at session level.
Examples
iex> AshScylla.DataLayer.QueryOptimizer.speculative_retry_cql(:99percentile, nil)
"USING SPECULATIVE_RETRY '99percentile'"
iex> AshScylla.DataLayer.QueryOptimizer.speculative_retry_cql(:none, nil)
"USING SPECULATIVE_RETRY 'NONE'"
iex> AshScylla.DataLayer.QueryOptimizer.speculative_retry_cql(:custom, 500)
"USING SPECULATIVE_RETRY '500ms'"
Generates CQL query options for Xandra execution.
Converts optimization hints into Xandra execute options.
This is an alias for optimize/2 that makes the intent explicit
when building Xandra calls directly.
@spec token_aware_hint(AshScylla.DataLayer.t()) :: keyword()
Generates a token-aware routing hint for the query.
When the partition key is known, this enables Xandra to route the query directly to the correct node.
Returns [token: partition_key_value] for Xandra's token-aware routing,
or an empty keyword list if no partition key can be determined.
Generates a token range query for partition-aware scanning.
Useful for parallel data processing where you want to split the token range across workers.
Parameters
table- The table namepartition_key- The partition key column namestart_token- Start of token range (inclusive)end_token- End of token range (exclusive)
Examples
iex> AshScylla.DataLayer.QueryOptimizer.token_range_query("users", "id", "-9223372036854775808", "0")
"SELECT * FROM users WHERE token(id) > -9223372036854775808 AND token(id) <= 0"