QuestDB 9.4.0

tosh1 pts0 comments

Release 9.4.0 · questdb/questdb · GitHub

//releases/show" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

//releases/show;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

questdb

questdb

Public

Notifications<br>You must be signed in to change notification settings

Fork<br>1.6k

Star<br>17k

9.4.0

Latest

Latest

Compare

Choose a tag to compare

Sorry, something went wrong.

Filter

Loading

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

No results found

View all tags

bluestreak01

released this

18 May 12:56

&middot;

29 commits

to master<br>since this release

9.4.0

7268629

QuestDB 9.4.0

QuestDB 9.4.0 introduces a compact, high-performance posting and covering index for SYMBOL columns, a local parquet metadata sidecar that unlocks row-group pruning, parallelised SAMPLE BY FILL with new cross-column FILL(PREV) syntax, three new window functions, and sparkline() / bar() text visualisations. It also delivers meaningful GROUP BY / hash-join speed-ups and fixes a number of correctness issues across the SQL planner, the WAL apply path, and the PGWire protocol.

For any questions or feedback, please join us on Slack or on Discourse.

See also our prettier release notes page.

Highlights

Posting and covering index for SYMBOL columns

A new INDEX TYPE POSTING for SYMBOL columns delivers ~13x smaller index files and 1.3-1.5x faster lookups vs. the BITMAP index, at a ~9% write-amplification cost. An optional INCLUDE (...) list builds a covering sidecar so queries that read only the indexed column plus the included columns skip the column files entirely:

CREATE TABLE trades (<br>ts TIMESTAMP,<br>sym SYMBOL INDEX TYPE POSTING INCLUDE (price, qty),<br>price DOUBLE,<br>qty INT<br>) TIMESTAMP(ts) PARTITION BY DAY;

ALTER TABLE trades<br>ALTER COLUMN sym ADD INDEX TYPE POSTING INCLUDE (price, qty);

Supported query shapes that benefit from the covering path include WHERE sym = 'X', WHERE sym IN (...), LATEST ON ts PARTITION BY sym, and SELECT DISTINCT sym. Covering data is ALP-compressed for FLOAT/DOUBLE, FoR bit-packed for integer types, and FSST-compressed for STRING/VARCHAR. Native AVX2 decoding fast paths kick in for common bit-widths.

A few practical notes:

⚠️ Drop the posting index before rolling back to an older QuestDB version. Pre-9.4.0 binaries do not recognise the new index type in column metadata and will refuse to open a table that has a posting index. If you need to downgrade, run ALTER TABLE ALTER COLUMN DROP INDEX on every posting-indexed column first.

High-cardinality SYMBOL columns benefit most — hundreds to thousands of distinct values on wide tables where the win from skipping full column files is largest.

The designated timestamp is auto-appended to INCLUDE when you supply an INCLUDE clause, so SHOW CREATE TABLE renders INCLUDE (price, qty) back as INCLUDE (price, qty, ts). Controlled by cairo.posting.index.auto.include.timestamp (default true).

Verify the covering path with EXPLAIN — the plan shows CoveringIndex on: sym with: ..., with op: latest for LATEST ON queries and op: distinct for SELECT DISTINCT. SHOW COLUMNS and table_columns() also expose new indexType and indexInclude fields.

Async GROUP BY and filter paths through the covering index are currently slower than the regular plan in some workloads. A follow-up release will close this gap. If EXPLAIN shows a query picking the covering path and you see a regression, opt that query out with /*+ no_covering */ (or /*+ no_index */ to disable indexing entirely) until the optimisations land.

See the posting index and covering index documentation for the full feature reference, encoding variants (POSTING DELTA / POSTING EF, both for benchmarking), and storage layout details. by @bluestreak01 in #6861

Local parquet metadata sidecar

Each parquet partition now ships with a compact binary _pm sidecar that stores column descriptors, per-row-group byte ranges, encodings and min/max statistics. The query planner reads pruning information from _pm without ever opening data.parquet, which is a prerequisite for efficient cold-storage scans. A migration (Mig940) generates _pm files for all existing parquet partitions on engine upgrade. by @RaphDal in...

index posting include covering column questdb

Related Articles