cockroachdb / cockroachdb/cockroach

Composite tuple IN filter on cross join causes full scan instead of point-lookup union

Open
#170,885 2 comments 0 reactions 0 assignees View on GitHub
A-sql-optimizer C-performance T-sql-queries
Dominant language
Go
Stars
32.5k
Forks
4.1k
PR merge metrics
PR metrics pending

Description

**Describe the problem**

Hi, CockroachDB developers, thanks for reading my report. I find a missed optimization in CockroachDB.

When filtering a cross join on two tables with primary keys using the natural SQL idiom
`WHERE (t0.pk, t1.pk) IN ((v1,v2), ...)` the optimizer fails to decompose the condition into a union of point‑lookup joins. Instead, it scans both tables entirely and applies a post‑filter, despite each tuple directly corresponding to exact primary key seeks. The equivalent but much more verbose `OR`‑of‑`AND` form produces an efficient plan.

**To Reproduce**

```sql
CREATE TABLE t0 (c0 INT PRIMARY KEY);
CREATE TABLE t1 (c0 INT PRIMARY KEY);
INSERT INTO t0 SELECT * FROM generate_series(1, 1000000);
INSERT INTO t1 SELECT * FROM generate_series(1, 1000);

EXPLAIN ANALYZE SELECT * FROM t0, t1 WHERE (t0.c0, t1.c0) IN ((0,0),(1,1));
-- Full cross join, 1M × 1K rows, ~80s

EXPLAIN ANALYZE SELECT * FROM t0, t1 WHERE (t0.c0=0 AND t1.c0=0) OR (t0.c0=1 AND t1.c0=1);
-- Union of two cross joins with point scans, ~2ms
```

**Expected behavior**
The first query should be transformed into the same union‑all plan that directly seeks on the primary key indexes, executing in milliseconds.
```
• distinct on: c0, c0
└── • union all
├── • cross join
│ ├── • scan t0@t0_pkey spans: [/0 - /0]
│ └── • scan t1@t1_pkey spans: [/0 - /0]
└── • cross join
├── • scan t0@t0_pkey spans: [/1 - /1]
└── • scan t1@t1_pkey spans: [/1 - /1]
```
**Actual behavior**
A full cross join of both tables is performed (1M × 1K rows scanned) with the `IN` predicate applied after the join, taking ~80 seconds and ignoring the primary keys entirely.
```
• cross join
│ pred: (c0, c0) IN ((0, 0), (1, 1))
├── • scan t0@t0_pkey spans: FULL SCAN (1,000,000 rows)
└── • scan t1@t1_pkey spans: FULL SCAN (1,000 rows)
```
**Environment:**
- CockroachDB version: v26.1.3 (x86_64-pc-linux-gnu, built 2026/04/16 16:56:33, go1.25.5) (same version as client)
- Server OS: ubuntu 22.04
- Client: cockroach sql

Jira issue: CRDB-64221

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.