Time-travel support
Snowflake supports time-travel, which means that querying the past is possible and queries stay consistent if the data in Snowflake is updated.When creating new epochs for the Database, DirectQuery automatically snapshots the current timestamp and use it. Querying past snapshots is done by using the
AT TIMESTAMP SQL syntax.
As such, when the historical data becomes unavailable, this is reflected in DirectQuery and queries against those old versions will fail.
For views, Atoti will retrieve all the underlying tables, and use their latest timestamp to query the view.
The logger atoti.server.directquery.query_resolution.time_travel is useful to retrieve the queries generated specifically for time-travel.
Vector supports
Only multi-rows vectors and multi-columns vectors are supported by Snowflake. The array type available in Snowflake does not offer powerful aggregation functions to work with them.Gotchas
Nullable fields
Snowflake can define fields with nullable types. DirectQuery is capable of detecting this and defines its internal model accordingly.While this is not a problem in itself, it can conflict with the rule in Atoti cubes that all levels must be based on non-nullable values. This does not create an issue of any sort as the local model is updated behind the scene, assigning a default value based on the type.
It has a side effect on the query performance, as DirectQuery must convert on-the-fly null values to their assigned default values, as well as adding extra conditions during joins to handle null values on both sides.
Connection pool configuration
DirectQuery uses the HikariCP connection pool to manage connections to Snowflake. It is possible to tune this connection pool by specifying a configuration file and providing its path with the system propertyhikaricp.configurationFile (via -Dhikaricp.configurationFile=path/to/hikari.properties).
Not all the parameters can be set that way, as some are set directly by DirectQuery.
The associated file format is:
Pool size
maximumPoolSize: if not set, the pool size is configured automatically by the DirectQuery connector, based on the number of CPU cores available.
Connection timeout
idleTimeout: the maximum time a connection can be idle before being closed. This parameter is not set by DirectQuery and defaults to the Hikari default.
Minimum idle connections
minimumIdle: the minimum number of idle connections that the pool will maintain. This parameter is not set by DirectQuery and defaults to the Hikari default.
Feeding warehouse
On modern cloud distributed databases such as Snowflake, a key design point is the separation of compute and storage. This allows to use different computing resources to process queries and brings flexibility and the capability to scale up and down the resources (and the associated bill!). On Snowflake, the compute resources are called warehouses. A bigger warehouse will process queries faster but will also cost more. The load on the external database of a DirectQuery application is quite particular:- At the application startup and refresh, many queries are performed on the database to initialize the cube and cache data in it (the hierarchies and aggregate providers).
- After the initial feeding, if the aggregate providers have been chosen wisely, most user queries will hit the cache data and actually never been run on the external database. Additionally, queries hitting the external database should most of the time be drill-down with a very reduced scope and should be easier to handle by Snowflake.
- one powerful warehouse, used during initial feeding and refresh, to guarantee faster startup and refresh times
- a regular warehouse, to serve the queries after the initial feeding in a cost-efficient manner