cockroachdb / cockroachdb/cockroach

colexec: consider short-circuting INTERSECT and EXCEPT when left table is empty

Open
#147,392 3 comments 0 reactions 0 assignees View on GitHub
C-performance 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**

Hi, CockroachDB developers,

Please consider such a query: SELECT * FROM empty_table INTERSECT SELECT * FROM not_empty_table;

Obviously, the above query always returns an empty set. I think it should return an empty set quickly. However, it waste much time scan full tables when executing.

I think this is a common case in actual production scenarios. It's important to clarify that **users might not intentionally perform INTERSECT operations on empty tables**. Rather, **they may be unaware that a table is empty**. For example, when data has been deleted by another user or process. If CockroachDB can address this performance bug, it would significantly improve query efficiency and save users's time in such cases.

Thank you for your time, looking forward to your reply!

**To Reproduce**
You can reproduce it as follow:
```
root@localhost:26257/defaultdb> CREATE TABLE t0(c0 INT8);
root@localhost:26257/defaultdb> CREATE TABLE t1(c1 INT8);
root@localhost:26257/defaultdb> INSERT INTO t1 SELECT i FROM generate_series(1, 100000000) AS i;
INSERT 0 100000000
Time: 659.156s total (execution 659.147s / network 0.009s)

root@localhost:26257/defaultdb> explain SELECT * FROM t0 INTERSECT SELECT * FROM t1;
info
----------------------------------------------------------------------------------
distribution: local
vectorized: true

• intersect

├── • scan
│ estimated row count: 1 (100% of the table; stats collected 16 hours ago)
│ table: t0@t0_pkey
│ spans: FULL SCAN

└── • scan
missing stats
table: t1@t1_pkey
spans: FULL SCAN

index recommendations: 2
1. type: index creation
SQL command: CREATE INDEX ON defaultdb.public.t0 (c0);
2. type: index creation
SQL command: CREATE INDEX ON defaultdb.public.t1 (c1);
(20 rows)

Time: 51ms total (execution 50ms / network 1ms)
root@localhost:26257/defaultdb> SELECT * FROM t0 INTERSECT SELECT * FROM t1;
c0
------
(0 rows)

Time: 1131.088s total (execution 1131.080s / network 0.009s)
```

**Expected behavior**
The query should return an empty set quickly.
```
root@localhost:26257/defaultdb> SELECT * FROM t0 INTERSECT SELECT * FROM t1;
c0
------
(0 rows)

Time: 0.0xxs total (execution 0.0xx s / network 0.00x s)
```
**Environment:**
Server version: CockroachDB CCL v24.3.13 (x86_64-pc-linux-gnu, built 2025/05/13 17:14:36, go1.22.8X:nocoverageredesign) (same version as client)
Client app: cockroach sql

Jira issue: CRDB-51029

Contributor guide

Open the contributing guide

Research direction

Start by running the supplied CREATE TABLE, INSERT, EXPLAIN, and INTERSECT reproduction against CockroachDB. Trace the query execution for an empty left table and verify that the INTERSECT returns the empty result without scanning the full right table.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.