Feature: symmetric first-row-per-partition query for super tables, e.g. FIRST_ROW(*)
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 25.1k
- Forks
- 5k
- Avg merge
- 4d 59m
- Merged PRs (30d)
- 7
Description
Summary
TDengine provides a highly optimized LAST_ROW(*) query per subtable via super table partitioning, but there is no symmetric high-performance way to retrieve the earliest row per subtable. This creates an API asymmetry that affects common IoT use cases such as device onboarding-time inspection, first-event debugging, and lifecycle analysis.
Current behavior
LAST_ROW(*) FROM super_table PARTITION BY tbnameis a first-class query with dedicated RocksDB cache (cache.rdb) and can return the latest row for hundreds of thousands of subtables in milliseconds.- Getting the earliest row per subtable requires one of the following workarounds, and each has a fundamental drawback:
FIRST(*) FROM super_table PARTITION BY tbname—FIRSTis column-level, so the returned values can come from different rows.ROW_NUMBER() OVER (PARTITION BY tbname ORDER BY ts)withWHERE rn = 1— supported from v3.4.2.0, but requires full table scan and has no row-cache optimization.SELECT tbname, FIRST(ts), FIRST(voltage), FIRST(current) ...— verbose, still column-level semantics, and easy to get wrong when schema evolves.
Desired behavior
A row-level, partition-aware earliest-row function with performance characteristics similar to LAST_ROW(*). For example:
SELECT FIRST_ROW(*) FROM super_table PARTITION BY tbname;
or an equivalent syntax/option that returns the complete earliest row per subtable with cache or index acceleration.
Use case / impact
- Device first-online state lookup across many subtables.
- First anomaly event inspection during device lifecycle analysis.
- Any scenario needing "first state per device" at scale without full-table-scan penalties.
Notes
- Asymmetric time-direction caching is understandable for append-only TSDB workloads, but the missing symmetric API makes some first-event analytics unnecessarily expensive.
- A cache-backed first-row path would complement the existing
cache.rdbdesign rather than replace it.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by examining the existing LAST_ROW() query path for super tables partitioned by tbname and its dedicated cache.rdb behavior. Compare it with the documented FIRST() and ROW_NUMBER() workarounds, then define how a complete earliest row per subtable should behave and how cache or index acceleration would be validated.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sql
- Domain
- databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100