cockroachdb / cockroachdb/cockroach

opt: missing rule to split soft-limited scan into union all

Open
#136,344 2 comments 0 reactions 0 assignees View on GitHub
A-sql-optimizer C-performance O-support P-3 T-sql-queries
Dominant language
Go
Stars
32.5k
Forks
4.1k
PR merge metrics
PR metrics pending

Description

We have exploration rule `SplitLimitedScanIntoUnionScans` which turns a limited constrained scan with multiple spans into a union-all of limited constrained scans. But I think we need an equivalent exploration rule for soft-limited constrained scans. Or alternatively, maybe we need one of the `SplitDisjunction` rules to fire here.

```sql
CREATE TABLE abc (a INT, b INT, c INT, PRIMARY KEY (a, b), INDEX (c));
CREATE TABLE de (d INT, e INT, PRIMARY KEY (d));
INSERT INTO abc SELECT i, i, i % 100 FROM generate_series(0, 99999) AS s(i);
INSERT INTO de SELECT generate_series(0, 99), 1;
ANALYZE abc;
ANALYZE de;

-- in this query, we can find an efficient union-all plan thanks to SplitLimitedScanIntoUnionScans
-- reads 20 rows from KV
EXPLAIN ANALYZE
SELECT *
FROM abc
LEFT JOIN de ON d = b
WHERE c IN (5, 7) AND (a, b) < (90000, 17)
ORDER BY a DESC, b DESC
LIMIT 10;

-- if we add a predicate on d, we can no longer find the union-all plan
-- reads 1900 rows from KV
EXPLAIN ANALYZE
SELECT *
FROM abc
LEFT JOIN de ON d = b
WHERE c IN (5, 7) AND (a, b) < (90000, 17)
AND d IS NULL
ORDER BY a DESC, b DESC
LIMIT 10;

-- if we manually rewrite to use union-all, it's much better
-- reads 200 rows from KV
EXPLAIN ANALYZE
SELECT *
FROM
(
SELECT *
FROM abc
WHERE c = 5 AND (a, b) < (90000, 17)
UNION ALL
SELECT *
FROM abc
WHERE c = 7 AND (a, b) < (90000, 17)
)
LEFT JOIN de ON d = b
WHERE d IS NULL
ORDER BY a DESC, b DESC
LIMIT 10;
```

Jira issue: CRDB-44979

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.