cockroachdb / cockroachdb/cockroach
opt: rewrite greatest(a, b) < c to (a < c AND b < c)
- Dominant language
- Go
- Stars
- 32.5k
- Forks
- 4.1k
- PR merge metrics
- PR metrics pending
Description
**Is your feature request related to a problem? Please describe.**
The index on a table only seems to be used for extremely simple conditionals. For example, consider a table with two integer values, `x` and `y`, indexed on `x`. On an example table, I see the following behavior for a range query:
```
EXPLAIN SELECT * FROM temp WHERE x < 15000;
info
---------------------------------------------------------------------------------------
distribution: local
vectorized: true
• index join
│ estimated row count: 15,047
│ table: temp@primary
│
└── • scan
estimated row count: 15,047 (15% of the table; stats collected 2 minutes ago)
table: temp@temp_x_idx
spans: (/NULL - /14999]
(11 rows)
Time: 2ms total (execution 2ms / network 0ms)
```
However, for slightly more complicated conditionals, the index is not used, and the estimated row count is very incorrect. For example, if I perform the following (equivalent) query:
```
EXPLAIN SELECT * FROM temp WHERE greatest(x, 3) < 15000;
info
-----------------------------------------------------------------------------------------
distribution: full
vectorized: true
• filter
│ estimated row count: 33,333
│ filter: greatest(x, 3) < 15000
│
└── • scan
estimated row count: 100,000 (100% of the table; stats collected 3 minutes ago)
table: temp@primary
spans: FULL SCAN
(11 rows)
```
A scan is used and the estimated row count is double what's expected. Here's a more realistic example that also doesn't use the index as I'd expect:
```
EXPLAIN SELECT * FROM temp WHERE greatest(x, y) < 15000;
info
------------------------------------------------------------------------------------------
distribution: full
vectorized: true
• filter
│ estimated row count: 33,333
│ filter: least(x, y) < 15000
│
└── • scan
estimated row count: 100,000 (100% of the table; stats collected 22 minutes ago)
table: temp@primary
spans: FULL SCAN
(11 rows)
Time: 2ms total (execution 2ms / network 1ms)
```
**Describe the solution you'd like**
I'd expect all three of the above queries to use the index when possible. The optimizer might consider rewriting these expressions, i.e. `greatest(a, b) < c -> a < c AND b < c` and `least(a, b) < c -> a < c OR b < c`. I'm new to cockroachdb, so not sure how much the optimizer already tries to rewrite conditionals, but if I do this `greatest` rewrite manually, I get the index behavior that I expect (i.e. `x < 15000 AND y < 15000` produces a `filter(index join(scan))`).
**Describe alternatives you've considered**
N/A
**Additional context**
N/A
Jira issue: CRDB-36336
Contributor guide
Assessment
This issue has not been assessed yet.