cockroachdb / cockroachdb/cockroach

sql: Suboptimal query plan generated by planner

Open
#171,890 4 comments 0 reactions 0 assignees View on GitHub
C-bug O-community T-sql-queries X-blathers-triaged
Dominant language
Go
Stars
32.5k
Forks
4.1k
PR merge metrics
PR metrics pending

Description

**Describe the problem**

Please describe the issue you observed, and any steps we can take to reproduce it:

Hi,

In the following test case, there is an index with HASH BUCKETs, the SELECT statement chooses to use this index on a small data size, which is suboptimal.

```
CREATE TABLE events (
tenant_id INT8 NOT NULL,
event_ts INT8 NOT NULL
);

INSERT INTO events(rowid, tenant_id, event_ts)
SELECT g, g % 8, 1700000000000000 + g
FROM generate_series(1, 1000) AS gs(g);

CREATE INDEX events_by_ts
ON events(event_ts ASC)
USING HASH WITH BUCKET_COUNT = 37
STORING (tenant_id);

EXPLAIN ANALYZE
SELECT COUNT(1)
FROM events
WHERE event_ts IS NOT NULL
GROUP BY tenant_id, event_ts
ORDER BY event_ts ASC
LIMIT 1;
-- info
-- planning time: 4ms
-- execution time: 13ms
-- distribution: local
-- plan type: custom
-- rows decoded from KV: 1,000 (39 KiB, 74 gRPC calls)
--
-- • limit
-- │ count: 1
-- │
-- └── • group (partial streaming)
-- │ sql nodes: n1
-- │ execution time: 1ms
-- │ sql cpu time: 1ms
-- │ actual row count: 1
-- │ group by: tenant_id, event_ts
-- │ ordered: +event_ts
-- │
-- └── • union all
-- │ sql nodes: n1
-- │ execution time: 4µs
-- │ sql cpu time: 4µs
-- │ actual row count: 1,000
-- │
-- ├── • union all
-- │ │ sql nodes: n1
-- │ │ execution time: 3µs
-- │ │ sql cpu time: 3µs
-- │ │ actual row count: 585
-- │ │
-- │ ├── • union all
-- │ │ │ sql nodes: n1
-- │ │ │ execution time: 3µs
-- │ │ │ sql cpu time: 3µs
-- │ │ │ actual row count: 373
-- │ │ │
-- │ │ ├── • union all
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ execution time: 2µs
-- │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ actual row count: 239
-- │ │ │ │
-- │ │ │ ├── • union all
-- │ │ │ │ │ sql nodes: n1
-- │ │ │ │ │ execution time: 2µs
-- │ │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ │ actual row count: 118
-- │ │ │ │ │
-- │ │ │ │ ├── • union all
-- │ │ │ │ │ │ sql nodes: n1
-- │ │ │ │ │ │ execution time: 2µs
-- │ │ │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ │ │ actual row count: 73
-- │ │ │ │ │ │
-- │ │ │ │ │ ├── • scan
-- │ │ │ │ │ │ sql nodes: n1
-- │ │ │ │ │ │ kv nodes: n1
-- │ │ │ │ │ │ KV time: 501µs
-- │ │ │ │ │ │ KV rows decoded: 33
-- │ │ │ │ │ │ sql cpu time: 109µs
-- │ │ │ │ │ │ actual row count: 33
-- │ │ │ │ │ │ missing stats
-- │ │ │ │ │ │ table: events@events_by_ts
-- │ │ │ │ │ │ spans: [/8 - /8]
-- │ │ │ │ │ │
-- │ │ │ │ │ └── • scan
-- │ │ │ │ │ sql nodes: n1
-- │ │ │ │ │ kv nodes: n1
-- │ │ │ │ │ KV time: 462µs
-- │ │ │ │ │ KV rows decoded: 40
-- │ │ │ │ │ sql cpu time: 42µs
-- │ │ │ │ │ actual row count: 40
-- │ │ │ │ │ missing stats
-- │ │ │ │ │ table: events@events_by_ts
-- │ │ │ │ │ spans: [/9 - /9]
-- │ │ │ │ │
-- │ │ │ │ └── • union all
-- │ │ │ │ │ sql nodes: n1
-- │ │ │ │ │ execution time: 2µs
-- │ │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ │ actual row count: 45
-- │ │ │ │ │
-- │ │ │ │ ├── • scan
-- │ │ │ │ │ sql nodes: n1
-- │ │ │ │ │ kv nodes: n1
-- │ │ │ │ │ KV time: 183µs
-- │ │ │ │ │ KV rows decoded: 13
-- │ │ │ │ │ sql cpu time: 23µs
-- │ │ │ │ │ actual row count: 13
-- │ │ │ │ │ missing stats
-- │ │ │ │ │ table: events@events_by_ts
-- │ │ │ │ │ spans: [/6 - /6]
-- │ │ │ │ │
-- │ │ │ │ └── • scan
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ kv nodes: n1
-- │ │ │ │ KV time: 203µs
-- │ │ │ │ KV rows decoded: 32
-- │ │ │ │ sql cpu time: 31µs
-- │ │ │ │ actual row count: 32
-- │ │ │ │ missing stats
-- │ │ │ │ table: events@events_by_ts
-- │ │ │ │ spans: [/7 - /7]
-- │ │ │ │
-- │ │ │ └── • union all
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ execution time: 2µs
-- │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ actual row count: 121
-- │ │ │ │
-- │ │ │ ├── • union all
-- │ │ │ │ │ sql nodes: n1
-- │ │ │ │ │ execution time: 2µs
-- │ │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ │ actual row count: 59
-- │ │ │ │ │
-- │ │ │ │ ├── • scan
-- │ │ │ │ │ sql nodes: n1
-- │ │ │ │ │ kv nodes: n1
-- │ │ │ │ │ KV time: 196µs
-- │ │ │ │ │ KV rows decoded: 31
-- │ │ │ │ │ sql cpu time: 28µs
-- │ │ │ │ │ actual row count: 31
-- │ │ │ │ │ missing stats
-- │ │ │ │ │ table: events@events_by_ts
-- │ │ │ │ │ spans: [/4 - /4]
-- │ │ │ │ │
-- │ │ │ │ └── • scan
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ kv nodes: n1
-- │ │ │ │ KV time: 175µs
-- │ │ │ │ KV rows decoded: 28
-- │ │ │ │ sql cpu time: 37µs
-- │ │ │ │ actual row count: 28
-- │ │ │ │ missing stats
-- │ │ │ │ table: events@events_by_ts
-- │ │ │ │ spans: [/5 - /5]
-- │ │ │ │
-- │ │ │ └── • union all
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ execution time: 2µs
-- │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ actual row count: 62
-- │ │ │ │
-- │ │ │ ├── • scan
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ kv nodes: n1
-- │ │ │ │ KV time: 310µs
-- │ │ │ │ KV rows decoded: 34
-- │ │ │ │ sql cpu time: 70µs
-- │ │ │ │ actual row count: 34
-- │ │ │ │ missing stats
-- │ │ │ │ table: events@events_by_ts
-- │ │ │ │ spans: [/2 - /2]
-- │ │ │ │
-- │ │ │ └── • scan
-- │ │ │ sql nodes: n1
-- │ │ │ kv nodes: n1
-- │ │ │ KV time: 244µs
-- │ │ │ KV rows decoded: 28
-- │ │ │ sql cpu time: 36µs
-- │ │ │ actual row count: 28
-- │ │ │ missing stats
-- │ │ │ table: events@events_by_ts
-- │ │ │ spans: [/3 - /3]
-- │ │ │
-- │ │ └── • union all
-- │ │ │ sql nodes: n1
-- │ │ │ execution time: 3µs
-- │ │ │ sql cpu time: 3µs
-- │ │ │ actual row count: 134
-- │ │ │
-- │ │ ├── • union all
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ execution time: 2µs
-- │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ actual row count: 81
-- │ │ │ │
-- │ │ │ ├── • union all
-- │ │ │ │ │ sql nodes: n1
-- │ │ │ │ │ execution time: 2µs
-- │ │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ │ actual row count: 57
-- │ │ │ │ │
-- │ │ │ │ ├── • scan
-- │ │ │ │ │ sql nodes: n1
-- │ │ │ │ │ kv nodes: n1
-- │ │ │ │ │ KV time: 170µs
-- │ │ │ │ │ KV rows decoded: 23
-- │ │ │ │ │ sql cpu time: 32µs
-- │ │ │ │ │ actual row count: 23
-- │ │ │ │ │ missing stats
-- │ │ │ │ │ table: events@events_by_ts
-- │ │ │ │ │ spans: [/0 - /0]
-- │ │ │ │ │
-- │ │ │ │ └── • scan
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ kv nodes: n1
-- │ │ │ │ KV time: 177µs
-- │ │ │ │ KV rows decoded: 34
-- │ │ │ │ sql cpu time: 36µs
-- │ │ │ │ actual row count: 34
-- │ │ │ │ missing stats
-- │ │ │ │ table: events@events_by_ts
-- │ │ │ │ spans: [/1 - /1]
-- │ │ │ │
-- │ │ │ └── • scan
-- │ │ │ sql nodes: n1
-- │ │ │ kv nodes: n1
-- │ │ │ KV time: 173µs
-- │ │ │ KV rows decoded: 24
-- │ │ │ sql cpu time: 30µs
-- │ │ │ actual row count: 24
-- │ │ │ missing stats
-- │ │ │ table: events@events_by_ts
-- │ │ │ spans: [/36 - /36]
-- │ │ │
-- │ │ └── • union all
-- │ │ │ sql nodes: n1
-- │ │ │ execution time: 2µs
-- │ │ │ sql cpu time: 2µs
-- │ │ │ actual row count: 53
-- │ │ │
-- │ │ ├── • scan
-- │ │ │ sql nodes: n1
-- │ │ │ kv nodes: n1
-- │ │ │ KV time: 156µs
-- │ │ │ KV rows decoded: 35
-- │ │ │ sql cpu time: 28µs
-- │ │ │ actual row count: 35
-- │ │ │ missing stats
-- │ │ │ table: events@events_by_ts
-- │ │ │ spans: [/34 - /34]
-- │ │ │
-- │ │ └── • scan
-- │ │ sql nodes: n1
-- │ │ kv nodes: n1
-- │ │ KV time: 136µs
-- │ │ KV rows decoded: 18
-- │ │ sql cpu time: 20µs
-- │ │ actual row count: 18
-- │ │ missing stats
-- │ │ table: events@events_by_ts
-- │ │ spans: [/35 - /35]
-- │ │
-- │ └── • union all
-- │ │ sql nodes: n1
-- │ │ execution time: 2µs
-- │ │ sql cpu time: 2µs
-- │ │ actual row count: 212
-- │ │
-- │ ├── • union all
-- │ │ │ sql nodes: n1
-- │ │ │ execution time: 2µs
-- │ │ │ sql cpu time: 2µs
-- │ │ │ actual row count: 100
-- │ │ │
-- │ │ ├── • union all
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ execution time: 2µs
-- │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ actual row count: 53
-- │ │ │ │
-- │ │ │ ├── • scan
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ kv nodes: n1
-- │ │ │ │ KV time: 197µs
-- │ │ │ │ KV rows decoded: 29
-- │ │ │ │ sql cpu time: 28µs
-- │ │ │ │ actual row count: 29
-- │ │ │ │ missing stats
-- │ │ │ │ table: events@events_by_ts
-- │ │ │ │ spans: [/32 - /32]
-- │ │ │ │
-- │ │ │ └── • scan
-- │ │ │ sql nodes: n1
-- │ │ │ kv nodes: n1
-- │ │ │ KV time: 198µs
-- │ │ │ KV rows decoded: 24
-- │ │ │ sql cpu time: 26µs
-- │ │ │ actual row count: 24
-- │ │ │ missing stats
-- │ │ │ table: events@events_by_ts
-- │ │ │ spans: [/33 - /33]
-- │ │ │
-- │ │ └── • union all
-- │ │ │ sql nodes: n1
-- │ │ │ execution time: 2µs
-- │ │ │ sql cpu time: 2µs
-- │ │ │ actual row count: 47
-- │ │ │
-- │ │ ├── • scan
-- │ │ │ sql nodes: n1
-- │ │ │ kv nodes: n1
-- │ │ │ KV time: 166µs
-- │ │ │ KV rows decoded: 23
-- │ │ │ sql cpu time: 30µs
-- │ │ │ actual row count: 23
-- │ │ │ missing stats
-- │ │ │ table: events@events_by_ts
-- │ │ │ spans: [/30 - /30]
-- │ │ │
-- │ │ └── • scan
-- │ │ sql nodes: n1
-- │ │ kv nodes: n1
-- │ │ KV time: 231µs
-- │ │ KV rows decoded: 24
-- │ │ sql cpu time: 37µs
-- │ │ actual row count: 24
-- │ │ missing stats
-- │ │ table: events@events_by_ts
-- │ │ spans: [/31 - /31]
-- │ │
-- │ └── • union all
-- │ │ sql nodes: n1
-- │ │ execution time: 2µs
-- │ │ sql cpu time: 2µs
-- │ │ actual row count: 112
-- │ │
-- │ ├── • union all
-- │ │ │ sql nodes: n1
-- │ │ │ execution time: 2µs
-- │ │ │ sql cpu time: 2µs
-- │ │ │ actual row count: 59
-- │ │ │
-- │ │ ├── • scan
-- │ │ │ sql nodes: n1
-- │ │ │ kv nodes: n1
-- │ │ │ KV time: 184µs
-- │ │ │ KV rows decoded: 23
-- │ │ │ sql cpu time: 28µs
-- │ │ │ actual row count: 23
-- │ │ │ missing stats
-- │ │ │ table: events@events_by_ts
-- │ │ │ spans: [/28 - /28]
-- │ │ │
-- │ │ └── • scan
-- │ │ sql nodes: n1
-- │ │ kv nodes: n1
-- │ │ KV time: 241µs
-- │ │ KV rows decoded: 36
-- │ │ sql cpu time: 42µs
-- │ │ actual row count: 36
-- │ │ missing stats
-- │ │ table: events@events_by_ts
-- │ │ spans: [/29 - /29]
-- │ │
-- │ └── • union all
-- │ │ sql nodes: n1
-- │ │ execution time: 2µs
-- │ │ sql cpu time: 2µs
-- │ │ actual row count: 53
-- │ │
-- │ ├── • scan
-- │ │ sql nodes: n1
-- │ │ kv nodes: n1
-- │ │ KV time: 186µs
-- │ │ KV rows decoded: 31
-- │ │ sql cpu time: 36µs
-- │ │ actual row count: 31
-- │ │ missing stats
-- │ │ table: events@events_by_ts
-- │ │ spans: [/26 - /26]
-- │ │
-- │ └── • scan
-- │ sql nodes: n1
-- │ kv nodes: n1
-- │ KV time: 160µs
-- │ KV rows decoded: 22
-- │ sql cpu time: 27µs
-- │ actual row count: 22
-- │ missing stats
-- │ table: events@events_by_ts
-- │ spans: [/27 - /27]
-- │
-- └── • union all
-- │ sql nodes: n1
-- │ execution time: 3µs
-- │ sql cpu time: 3µs
-- │ actual row count: 415
-- │
-- ├── • union all
-- │ │ sql nodes: n1
-- │ │ execution time: 2µs
-- │ │ sql cpu time: 2µs
-- │ │ actual row count: 202
-- │ │
-- │ ├── • union all
-- │ │ │ sql nodes: n1
-- │ │ │ execution time: 2µs
-- │ │ │ sql cpu time: 2µs
-- │ │ │ actual row count: 103
-- │ │ │
-- │ │ ├── • union all
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ execution time: 2µs
-- │ │ │ │ sql cpu time: 2µs
-- │ │ │ │ actual row count: 48
-- │ │ │ │
-- │ │ │ ├── • scan
-- │ │ │ │ sql nodes: n1
-- │ │ │ │ kv nodes: n1
-- │ │ │ │ KV time: 145µs
-- │ │ │ │ KV rows decoded: 22
-- │ │ │ │ sql cpu time: 21µs
-- │ │ │ │ actual row count: 22
-- │ │ │ │ missing stats
-- │ │ │ │ table: events@events_by_ts
-- │ │ │ │ spans: [/24 - /24]
-- │ │ │ │
-- │ │ │ └── • scan
-- │ │ │ sql nodes: n1
-- │ │ │ kv nodes: n1
-- │ │ │ KV time: 182µs
-- │ │ │ KV rows decoded: 26
-- │ │ │ sql cpu time: 24µs
-- │ │ │ actual row count: 26
-- │ │ │ missing stats
-- │ │ │ table: events@events_by_ts
-- │ │ │ spans: [/25 - /25]
-- │ │ │
-- │ │ └── • union all
-- │ │ │ sql nodes: n1
-- │ │ │ execution time: 2µs
-- │ │ │ sql cpu time: 2µs
-- │ │ │ actual row count: 55
-- │ │ │
-- │ │ ├── • scan
-- │ │ │ sql nodes: n1
-- │ │ │ kv nodes: n1
-- │ │ │ KV time: 156µs
-- │ │ │ KV rows decoded: 28
-- │ │ │ sql cpu time: 39µs
-- │ │ │ actual row count: 28
-- │ │ │ missing stats
-- │ │ │ table: events@events_by_ts
-- │ │ │ spans: [/22 - /22]
-- │ │ │
-- │ │ └── • scan
-- │ │ sql nodes: n1
-- │ │ kv nodes: n1
-- │ │ KV time: 203µs
-- │ │ KV rows decoded: 27
-- │ │ sql cpu time: 26µs
-- │ │ actual row count: 27
-- │ │ missing stats
-- │ │ table: events@events_by_ts
-- │ │ spans: [/23 - /23]
-- │ │
-- │ └── • union all
-- │ │ sql nodes: n1
-- │ │ execution time: 2µs
-- │ │ sql cpu time: 2µs
-- │ │ actual row count: 99
-- │ │
-- │ ├── • union all
-- │ │ │ sql nodes: n1
-- │ │ │ execution time: 2µs
-- │ │ │ sql cpu time: 2µs
-- │ │ │ actual row count: 49
-- │ │ │
-- │ │ ├── • scan
-- │ │ │ sql nodes: n1
-- │ │ │ kv nodes: n1
-- │ │ │ KV time: 183µs
-- │ │ │ KV rows decoded: 26
-- │ │ │ sql cpu time: 45µs
-- │ │ │ actual row count: 26
-- │ │ │ missing stats
-- │ │ │ table: events@events_by_ts
-- │ │ │ spans: [/20 - /20]
-- │ │ │
-- │ │ └── • scan
-- │ │ sql nodes: n1
-- │ │ kv nodes: n1
-- │ │ KV time: 168µs
-- │ │ KV rows decoded: 23
-- │ │ sql cpu time: 30µs
-- │ │ actual row count: 23
-- │ │ missing stats
-- │ │ table: events@events_by_ts
-- │ │ spans: [/21 - /21]
-- │ │
-- │ └── • union all
-- │ │ sql nodes: n1
-- │ │ execution time: 2µs
-- │ │ sql cpu time: 2µs
-- │ │ actual row count: 50
-- │ │
-- │ ├── • scan
-- │ │ sql nodes: n1
-- │ │ kv nodes: n1
-- │ │ KV time: 235µs
-- │ │ KV rows decoded: 28
-- │ │ sql cpu time: 29µs
-- │ │ actual row count: 28
-- │ │ missing stats
-- │ │ table: events@events_by_ts
-- │ │ spans: [/18 - /18]
-- │ │
-- │ └── • scan
-- │ sql nodes: n1
-- │ kv nodes: n1
-- │ KV time: 188µs
-- │ KV rows decoded: 22
-- │ sql cpu time: 28µs
-- │ actual row count: 22
-- │ missing stats
-- │ table: events@events_by_ts
-- │ spans: [/19 - /19]
-- │
-- └── • union all
-- │ sql nodes: n1
-- │ execution time: 3µs
-- │ sql cpu time: 3µs
-- │ actual row count: 213
-- │
-- ├── • union all
-- │ │ sql nodes: n1
-- │ │ execution time: 2µs
-- │ │ sql cpu time: 2µs
-- │ │ actual row count: 101
-- │ │
-- │ ├── • union all
-- │ │ │ sql nodes: n1
-- │ │ │ execution time: 2µs
-- │ │ │ sql cpu time: 2µs
-- │ │ │ actual row count: 47
-- │ │ │
-- │ │ ├── • scan
-- │ │ │ sql nodes: n1
-- │ │ │ kv nodes: n1
-- │ │ │ KV time: 285µs
-- │ │ │ KV rows decoded: 18
-- │ │ │ sql cpu time: 26µs
-- │ │ │ actual row count: 18
-- │ │ │ missing stats
-- │ │ │ table: events@events_by_ts
-- │ │ │ spans: [/16 - /16]
-- │ │ │
-- │ │ └── • scan
-- │ │ sql nodes: n1
-- │ │ kv nodes: n1
-- │ │ KV time: 210µs
-- │ │ KV rows decoded: 29
-- │ │ sql cpu time: 38µs
-- │ │ actual row count: 29
-- │ │ missing stats
-- │ │ table: events@events_by_ts
-- │ │ spans: [/17 - /17]
-- │ │
-- │ └── • union all
-- │ │ sql nodes: n1
-- │ │ execution time: 2µs
-- │ │ sql cpu time: 2µs
-- │ │ actual row count: 54
-- │ │
-- │ ├── • scan
-- │ │ sql nodes: n1
-- │ │ kv nodes: n1
-- │ │ KV time: 197µs
-- │ │ KV rows decoded: 30
-- │ │ sql cpu time: 26µs
-- │ │ actual row count: 30
-- │ │ missing stats
-- │ │ table: events@events_by_ts
-- │ │ spans: [/14 - /14]
-- │ │
-- │ └── • scan
-- │ sql nodes: n1
-- │ kv nodes: n1
-- │ KV time: 178µs
-- │ KV rows decoded: 24
-- │ sql cpu time: 24µs
-- │ actual row count: 24
-- │ missing stats
-- │ table: events@events_by_ts
-- │ spans: [/15 - /15]
-- │
-- └── • union all
-- │ sql nodes: n1
-- │ execution time: 2µs
-- │ sql cpu time: 2µs
-- │ actual row count: 112
-- │
-- ├── • union all
-- │ │ sql nodes: n1
-- │ │ execution time: 2µs
-- │ │ sql cpu time: 2µs
-- │ │ actual row count: 64
-- │ │
-- │ ├── • scan
-- │ │ sql nodes: n1
-- │ │ kv nodes: n1
-- │ │ KV time: 190µs
-- │ │ KV rows decoded: 24
-- │ │ sql cpu time: 39µs
-- │ │ actual row count: 24
-- │ │ missing stats
-- │ │ table: events@events_by_ts
-- │ │ spans: [/12 - /12]
-- │ │
-- │ └── • scan
-- │ sql nodes: n1
-- │ kv nodes: n1
-- │ KV time: 176µs
-- │ KV rows decoded: 40
-- │ sql cpu time: 28µs
-- │ actual row count: 40
-- │ missing stats
-- │ table: events@events_by_ts
-- │ spans: [/13 - /13]
-- │
-- └── • union all
-- │ sql nodes: n1
-- │ execution time: 2µs
-- │ sql cpu time: 2µs
-- │ actual row count: 48
-- │
-- ├── • scan
-- │ sql nodes: n1
-- │ kv nodes: n1
-- │ KV time: 256µs
-- │ KV rows decoded: 21
-- │ sql cpu time: 32µs
-- │ actual row count: 21
-- │ missing stats
-- │ table: events@events_by_ts
-- │ spans: [/10 - /10]
-- │
-- └── • scan
-- sql nodes: n1
-- kv nodes: n1
-- KV time: 190µs
-- KV rows decoded: 27
-- sql cpu time: 28µs
-- actual row count: 27
-- missing stats
-- table: events@events_by_ts
-- spans: [/11 - /11]

SET plan_cache_mode = force_generic_plan;

PREPARE q (int8, int8) AS
SELECT COUNT($1)
FROM events
WHERE event_ts IS NOT NULL
GROUP BY tenant_id, event_ts
ORDER BY event_ts ASC
LIMIT $2;

EXPLAIN ANALYZE EXECUTE q(1, 1);
-- info
-- planning time: 578µs
-- execution time: 2ms
-- distribution: local
-- plan type: generic, re-optimized
-- rows decoded from KV: 1,000 (39 KiB, 1 gRPC calls)
--
-- • limit
-- │ count: 1
-- │
-- └── • group (partial streaming)
-- │ sql nodes: n1
-- │ execution time: 721µs
-- │ sql cpu time: 721µs
-- │ actual row count: 1
-- │ group by: tenant_id, event_ts
-- │ ordered: +event_ts
-- │
-- └── • render
-- │ execution time: 9µs
-- │ sql cpu time: 9µs
-- │ actual row count: 1,000
-- │
-- └── • sort
-- │ sql nodes: n1
-- │ execution time: 73µs
-- │ sql cpu time: 73µs
-- │ actual row count: 1,000
-- │ order: +event_ts
-- │
-- └── • scan
-- sql nodes: n1
-- kv nodes: n1
-- KV time: 805µs
-- KV rows decoded: 1,000
-- sql cpu time: 297µs
-- actual row count: 1,000
-- missing stats
-- table: events@events_pkey
-- spans: FULL SCAN
```
**To Reproduce**

What did you do? Describe in your own words.

If possible, provide steps to reproduce the behavior:

I build and run CockroachDB f0bf32430c4960bfdad6d867e6df0e67079aeee1 in CLI

**Expected behavior**
The SELECT statement should generate the better query plan like the prepared statement.

**Additional data / screenshots**
If the problem is SQL-related, include a copy of the SQL query and the schema
of the supporting tables.

If a node in your cluster encountered a fatal error, supply the contents of the
log directories (at minimum of the affected node(s), but preferably all nodes).

Note that log files can contain confidential information. Please continue
creating this issue, but contact support@cockroachlabs.com to submit the log
files in private.

If applicable, add screenshots to help explain your problem.

**Environment:**
- CockroachDB version [f0bf32430c4960bfdad6d867e6df0e67079aeee1]
- Server OS: [Linux]
- Client app [`cockroach sql`, JDBC]

**Additional context**
What was the impact?

Add any other context about the problem here.

Jira issue: CRDB-65024

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the supplied CREATE TABLE, HASH index, and SELECT in CockroachDB, then inspect the EXPLAIN ANALYZE output: it shows the planner reading all 1,000 rows across hash buckets despite LIMIT 1. Locate the SQL optimizer/planner paths that choose an index and estimate its cost, and add or run a regression test for this query. Done means the planner chooses a less costly plan for the small dataset.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, sql
Domain
databases, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.