Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

opt: avoid generating trivial constrained scans #114332

Merged
merged 2 commits into from
Nov 15, 2023

Conversation

DrewKimball
Copy link
Collaborator

opt: extend constraint Contains method to handle common prefix

This patch extends the logic of Constraint.Contains to handle cases
when the columns of the left and right constraints differ beyond a common
prefix. The spans of one constraint can be compared with those of another
for containment when the following conditions are satisfied:

  1. The common prefix between the left and right columns is non-empty.
  2. Only one constraint can contain keys beyond the common prefix length.

These conditions ensure comparisons are valid by ensuring that comparison
only requires columns from the common prefix. Columns are only needed for
key comparisons up to the length of the shorter key, and the above conditions
guarantee that at least one key is always within the common prefix length.

Informs #114250

Release note: None

opt: avoid generating trivial constrained scans

This patch adds a check to the GenerateConstrainedScans optimizer rule
to prevent it from building trivial constrained scans that only use the
table's (non-selective) check constraints. This ensures that the resulting
plan will show a full scan as expected, and also prevents suboptimal index
joins in some cases.

Fixes #114250

Release note (sql change): The optimizer will no longer generate a
constrained scan that only uses filters from a check constraint. This
prevents cases where a constrained scan actually scans the entire table
because the constraints aren't selective.

@DrewKimball DrewKimball requested a review from a team as a code owner November 13, 2023 04:01
@DrewKimball DrewKimball requested review from rharding6373 and removed request for a team November 13, 2023 04:01
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@DrewKimball DrewKimball requested a review from a team November 13, 2023 19:06
Copy link
Collaborator

@mgartner mgartner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm: Great find and fix!

Reviewed 4 of 4 files at r1, 6 of 6 files at r2, all commit messages.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @DrewKimball and @rharding6373)


pkg/sql/opt/exec/execbuilder/testdata/explain line 2400 at r2 (raw file):

      └── k:6 = a:1 [outer=(1,6), constraints=(/1: (/NULL - ]; /6: (/NULL - ]), fd=(1)==(6), (6)==(1)]

# Regression test for #114250 - the EXPLAIN output should indicate a full scan.

nit: Not sure you really need this test. Either way, the message is confusing IMO since the fix doesn't have much to do about the EXPLAIN output—it's fixing a nonsense plan.


pkg/sql/opt/xform/testdata/rules/select line 2599 at r2 (raw file):

# scans the whole table using the table's check constraints.
exec-ddl
CREATE TABLE t114250 (x INT PRIMARY KEY USING HASH, y INT NOT NULL);

nit: it might be nice to have a test case with an explicit check constraint too.


pkg/sql/opt/constraint/constraint_test.go line 276 at r1 (raw file):

			"/1/4: [/1 - /1]",
			"/1: [/1 - /1]",
			true,

nit: missing field names here. You can fix the existing test cases above without field names too if you'd like.

This patch extends the logic of `Constraint.Contains` to handle cases
when the columns of the left and right constraints differ beyond a common
prefix. The spans of one constraint can be compared with those of another
for containment when the following conditions are satisfied:
1. The common prefix between the left and right columns is non-empty.
2. Only one constraint can contain keys beyond the common prefix length.

These conditions ensure comparisons are valid by ensuring that comparison
only requires columns from the common prefix. Columns are only needed for
key comparisons up to the length of the shorter key, and the above conditions
guarantee that at least one key is always within the common prefix length.

Informs cockroachdb#114250

Release note: None
Copy link
Collaborator Author

@DrewKimball DrewKimball left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @mgartner and @rharding6373)


pkg/sql/opt/exec/execbuilder/testdata/explain line 2400 at r2 (raw file):

Previously, mgartner (Marcus Gartner) wrote…

nit: Not sure you really need this test. Either way, the message is confusing IMO since the fix doesn't have much to do about the EXPLAIN output—it's fixing a nonsense plan.

Done.


pkg/sql/opt/xform/testdata/rules/select line 2599 at r2 (raw file):

Previously, mgartner (Marcus Gartner) wrote…

nit: it might be nice to have a test case with an explicit check constraint too.

Good idea, done. Actually, it turns out you can't use USING HASH for optimizer tests anyway. I'm not sure why it worked before, but it seems like it wasn't actually testing what I wanted it to.


pkg/sql/opt/constraint/constraint_test.go line 276 at r1 (raw file):

Previously, mgartner (Marcus Gartner) wrote…

nit: missing field names here. You can fix the existing test cases above without field names too if you'd like.

Oh, good catch. Fixed it.

This patch adds a check to the `GenerateConstrainedScans` optimizer rule
to prevent it from building trivial constrained scans that only use the
table's (non-selective) check constraints. This ensures that the resulting
plan will show a full scan as expected, and also prevents suboptimal index
joins in some cases.

Fixes cockroachdb#114250

Release note (sql change): The optimizer will no longer generate a
constrained scan that only uses filters from a check constraint. This
prevents cases where a constrained scan actually scans the entire table
because the constraints aren't selective.
@DrewKimball
Copy link
Collaborator Author

TFTR!

bors r+

@DrewKimball DrewKimball added the backport-23.2.x Flags PRs that need to be backported to 23.2. label Nov 14, 2023
Copy link
Collaborator

@rharding6373 rharding6373 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (and 1 stale) (waiting on @mgartner)


pkg/sql/opt/constraint/columns.go line 101 at r3 (raw file):

	}
	length := 1
	for i := 0; i < len(c.otherCols) && i < len(other.otherCols); i++ {

TIL about this nice alternative to using two variables to iterate over slices. Cool trick!

@craig
Copy link
Contributor

craig bot commented Nov 14, 2023

Build failed (retrying...):

@craig
Copy link
Contributor

craig bot commented Nov 14, 2023

Build failed (retrying...):

Copy link
Collaborator

@mgartner mgartner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm_strong:

Reviewed 8 of 8 files at r3, 8 of 8 files at r4, all commit messages.
Reviewable status: :shipit: complete! 2 of 0 LGTMs obtained (waiting on @DrewKimball)

@craig
Copy link
Contributor

craig bot commented Nov 15, 2023

Build succeeded:

@craig craig bot merged commit d9940ef into cockroachdb:master Nov 15, 2023
8 checks passed
@DrewKimball DrewKimball deleted the constraint branch November 15, 2023 20:06
DrewKimball added a commit to DrewKimball/cockroach that referenced this pull request Feb 22, 2024
This commit recovers the improvement which was made in cockroachdb#114332 and
reverted in cockroachdb#114744. Constrained scans are no longer generated when the
constraint is implied by the table's check constraints, except for
singleton tables (which are statically guaranteed to have one row).

This omission is necessary because a "trivial" constraint for a singleton
table allows the scan to use a KV Get request instead of a Scan, which
allows for some low-level optimizations. Preventing this optimization
regresses performance of an internal query on the `system.span_count`
table, which led to the failures seen in cockroachdb#114470.

There is no release note, since the release note from cockroachdb#114332 still
applies.

Fixes cockroachdb#114470

Release note: None
craig bot pushed a commit that referenced this pull request Feb 29, 2024
119505: opt: add back the fix for trivial constrained scans r=mgartner a=DrewKimball

This commit recovers the improvement which was made in #114332 and reverted in #114744. Constrained scans are no longer generated when the constraint is implied by the table's check constraints, except for singleton tables (which are statically guaranteed to have one row).

This omission is necessary because a "trivial" constraint for a singleton table allows the scan to use a KV Get request instead of a Scan, which allows for some low-level optimizations. Preventing this optimization regresses performance of an internal query on the `system.span_count` table, which led to the failures seen in #114470.

There is no release note, since the release note from #114332 still applies.

Fixes #114470

Release note: None

119721: authors: add bhaskar to authors r=nameisbhaskar a=nameisbhaskar

Release note: None
Epic: None

Co-authored-by: Drew Kimball <drewk@cockroachlabs.com>
Co-authored-by: Bhaskarjyoti Bora <bhaskar.bora@cockroachlabs.com>
DrewKimball added a commit to DrewKimball/cockroach that referenced this pull request Jul 3, 2024
This commit recovers the improvement which was made in cockroachdb#114332 and
reverted in cockroachdb#114744. Constrained scans are no longer generated when the
constraint is implied by the table's check constraints, except for
singleton tables (which are statically guaranteed to have one row).

This omission is necessary because a "trivial" constraint for a singleton
table allows the scan to use a KV Get request instead of a Scan, which
allows for some low-level optimizations. Preventing this optimization
regresses performance of an internal query on the `system.span_count`
table, which led to the failures seen in cockroachdb#114470.

There is no release note, since the release note from cockroachdb#114332 still
applies.

Fixes cockroachdb#114470

Release note: None
DrewKimball added a commit to DrewKimball/cockroach that referenced this pull request Jul 3, 2024
This commit recovers the improvement which was made in cockroachdb#114332 and
reverted in cockroachdb#114744. Constrained scans are no longer generated when the
constraint is implied by the table's check constraints, except for
singleton tables (which are statically guaranteed to have one row).

This omission is necessary because a "trivial" constraint for a singleton
table allows the scan to use a KV Get request instead of a Scan, which
allows for some low-level optimizations. Preventing this optimization
regresses performance of an internal query on the `system.span_count`
table, which led to the failures seen in cockroachdb#114470.

There is no release note, since the release note from cockroachdb#114332 still
applies.

Fixes cockroachdb#114470

Release note: None
DrewKimball added a commit to DrewKimball/cockroach that referenced this pull request Jul 3, 2024
This commit recovers the improvement which was made in cockroachdb#114332 and
reverted in cockroachdb#114744. Constrained scans are no longer generated when the
constraint is implied by the table's check constraints, except for
singleton tables (which are statically guaranteed to have one row).

This omission is necessary because a "trivial" constraint for a singleton
table allows the scan to use a KV Get request instead of a Scan, which
allows for some low-level optimizations. Preventing this optimization
regresses performance of an internal query on the `system.span_count`
table, which led to the failures seen in cockroachdb#114470.

There is no release note, since the release note from cockroachdb#114332 still
applies.

Fixes cockroachdb#114470

Release note: None
blathers-crl bot pushed a commit that referenced this pull request Jul 10, 2024
This commit recovers the improvement which was made in #114332 and
reverted in #114744. Constrained scans are no longer generated when the
constraint is implied by the table's check constraints, except for
singleton tables (which are statically guaranteed to have one row).

This omission is necessary because a "trivial" constraint for a singleton
table allows the scan to use a KV Get request instead of a Scan, which
allows for some low-level optimizations. Preventing this optimization
regresses performance of an internal query on the `system.span_count`
table, which led to the failures seen in #114470.

There is no release note, since the release note from #114332 still
applies.

Fixes #114470

Release note: None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-23.2.x Flags PRs that need to be backported to 23.2.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

sql: Improve planGist to show Full Scan on hash-sharded indexes when entire set is read
4 participants