Skip to content

opt: no limit on spans created by GenerateConstrainedScans #167620

@michae2

Description

@michae2

For queries with multiple IN sets covered by a secondary index, the optimizer's GenerateConstrainedScans rule can end up creating an unbounded number of spans on that secondary index, which blows out planning time. Here's an example:

SET CLUSTER SETTING sql.stats.automatic_collection.enabled = off;

CREATE TABLE tuvwxyz (t INT, u INT, v INT, w INT, x INT, y INT, z INT);

-- say the table has 1b rows
ALTER TABLE tuvwxyz INJECT STATISTICS '[
      {
          "avg_size": 9,
          "columns": [
              "rowid"
          ],
          "created_at": "2026-04-06 19:00:00.000000",
          "delay_delete": false,
          "distinct_count": 1000000000,
          "id": 1164678429724573697,
          "name": "__auto__",
          "null_count": 0,
          "row_count": 1000000000
      }
]';

-- takes 2ms to plan the full scan on my laptop
EXPLAIN
SELECT *
FROM tuvwxyz
WHERE t IN (10, 20, 30, 40, 50, 60, 70, 80, 90)
AND u IN (100, 200, 300, 400, 500, 600, 700, 800, 900)
AND v IN (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000)
AND w IN (10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000)
AND x IN (100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000)
AND y IN (1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000)
AND z IN (10000000, 20000000, 30000000, 40000000, 50000000, 60000000, 70000000, 80000000, 90000000);

CREATE INDEX ON tuvwxyz (t, u, v, w, x, y, z);

-- takes 3672ms to plan the constrained scan with almost 5m spans
EXPLAIN
SELECT *
FROM tuvwxyz
WHERE t IN (10, 20, 30, 40, 50, 60, 70, 80, 90)
AND u IN (100, 200, 300, 400, 500, 600, 700, 800, 900)
AND v IN (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000)
AND w IN (10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000)
AND x IN (100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000)
AND y IN (1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, 9000000)
AND z IN (10000000, 20000000, 30000000, 40000000, 50000000, 60000000, 70000000, 80000000, 90000000);

We already have span limits in GenerateSplitScan and GenerateLocalityOptimizedScan. We should add a span limit to GenerateConstrainedScans.

Jira issue: CRDB-62557

Metadata

Metadata

Assignees

Labels

A-sql-optimizerSQL logical planning and optimizations.C-enhancementSolution expected to add code/behavior + preserve backward-compat (pg compat issues are exception)O-supportWould prevent or help troubleshoot a customer escalation - bugs, missing observability/tooling, docsT-sql-queriesSQL Queries Teambranch-release-25.4Used to mark GA and release blockers and technical advisories for 25.4branch-release-25.4.10-rcbranch-release-26.1Used to mark GA and release blockers, technical advisories, and bugs for 26.1branch-release-26.2Used to mark GA and release blockers, technical advisories, and bugs for 26.2target-release-25.4.11target-release-26.1.5target-release-26.2.1target-release-26.3.0v25.4.10

Type

No type
No fields configured for issues without a type.

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions