Skip to content

opt: use transitive equalities to infer filters#43194

Merged
craig[bot] merged 1 commit intocockroachdb:masterfrom
rytaft:push-down
Dec 17, 2019
Merged

opt: use transitive equalities to infer filters#43194
craig[bot] merged 1 commit intocockroachdb:masterfrom
rytaft:push-down

Conversation

@rytaft
Copy link
Copy Markdown
Collaborator

@rytaft rytaft commented Dec 16, 2019

Previously, the optimizer was not inferring all possible filters
based on equality conditions. For example, consider a query such
as:

SELECT * FROM t
JOIN u ON t.a = u.a
JOIN v ON u.a = v.a
JOIN w ON v.a = w.a
WHERE t.a = 5;

Ideally, the optimizer should infer additional filter conditions
u.a = 5 AND v.a = 5 AND w.a = 5 based on the equality conditions.
However, this was not occurring because the optimizer only considered
equality conditions that were at the same level in the query tree as the
filter to be mapped. Now the optimizer also considers equality conditions
that are further down in the tree, so that additional filters can
be inferred based on transitive equalities.

Informs #43039

Release note (performance improvement): The optimizer can now infer
additional filter conditions in some cases based on transitive equalities
between columns.

@rytaft rytaft requested a review from a team as a code owner December 16, 2019 17:48
@cockroach-teamcity
Copy link
Copy Markdown
Member

This change is Reviewable

@rytaft
Copy link
Copy Markdown
Collaborator Author

rytaft commented Dec 16, 2019

cc @jordanlewis

@awoods187
Copy link
Copy Markdown

This is super cool! Do we have some benchmarks on perf improvements? Does this introduce any additional overhead that we should be concerned about?

Copy link
Copy Markdown
Member

@RaduBerinde RaduBerinde left a comment

Choose a reason for hiding this comment

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

Nice! :lgtm:

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @justinj, @RaduBerinde, and @rytaft)


pkg/sql/opt/norm/join.go, line 133 at r1 (raw file):

// equality conditions in filters that connect the two groups. If so,
// canMapJoinOpEquivalenceGroup returns true.
func (c *CustomFuncs) canMapJoinOpEquivalenceGroup(

[nit] consider expanding the comment to mention equivFD


pkg/sql/opt/norm/testdata/rules/join, line 1123 at r1 (raw file):

                └── variable: k [type=int]

exec-ddl

Would it be possible to come up with a simpler testcase, similar to the other ones?

Copy link
Copy Markdown
Member

@jordanlewis jordanlewis left a comment

Choose a reason for hiding this comment

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

Awesome, thanks for turning this around in record time!

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

Previously, the optimizer was not inferring all possible filters
based on equality conditions. For example, consider a query such
as:

SELECT * FROM t
JOIN u ON t.a = u.a
JOIN v ON u.a = v.a
JOIN w ON v.a = w.a
WHERE t.a = 5;

Ideally, the optimizer should infer additional filter conditions
u.a = 5 AND v.a = 5 AND w.a = 5 based on the equality conditions.
However, this was not occurring because the optimizer only considered
equality conditions that were at the same level in the query tree as the
filter to be mapped. Now the optimizer also considers equality conditions
that are further down in the tree, so that additional filters can
be inferred based on transitive equalities.

Informs cockroachdb#43039

Release note (performance improvement): The optimizer can now infer
additional filter conditions in some cases based on transitive equalities
between columns.
@rytaft rytaft force-pushed the push-down branch 2 times, most recently from 64f0a90 to 0daebf1 Compare December 16, 2019 21:33
Copy link
Copy Markdown
Collaborator Author

@rytaft rytaft left a comment

Choose a reason for hiding this comment

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

TFTR!

Do we have some benchmarks on perf improvements?

I'm running the new benchdiff tool now, but I'd be very surprised if this causes any significant changes. If anything it should improve planning performance slightly since I changed the code to avoid some redundant computation, but I doubt it will change many plans. In general we were already doing a pretty good job of inferring filters (note that no other test cases changed as a result of this fix).

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


pkg/sql/opt/norm/join.go, line 133 at r1 (raw file):

Previously, RaduBerinde wrote…

[nit] consider expanding the comment to mention equivFD

Done.


pkg/sql/opt/norm/testdata/rules/join, line 1123 at r1 (raw file):

Previously, RaduBerinde wrote…

Would it be possible to come up with a simpler testcase, similar to the other ones?

Done.

Copy link
Copy Markdown
Contributor

@andy-kimball andy-kimball left a comment

Choose a reason for hiding this comment

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

Good to make it complete, since it can be frustrating to change a query (like adding a join) and then have performance inexplicably fall off a cliff.

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

@rytaft
Copy link
Copy Markdown
Collaborator Author

rytaft commented Dec 16, 2019

Here are the results -- looks pretty good! (only showing tests with a pos or neg delta -- most of them didn't change):

name                                      old time/op    new time/op    delta
Chain/chain-19/Explore-4                    4.08ms ±31%    1.91ms ±11%  -53.19%  (p=0.000 n=10+9)
Chain/chain-18/Explore-4                    3.24ms ±14%    1.78ms ± 8%  -44.98%  (p=0.000 n=10+9)
Chain/chain-16/Explore-4                    2.59ms ±34%    1.48ms ± 8%  -42.88%  (p=0.000 n=10+9)
Chain/chain-17/Explore-4                    2.80ms ±10%    1.68ms ±17%  -39.97%  (p=0.000 n=10+10)
Chain/chain-15/Explore-4                    2.00ms ± 9%    1.34ms ±18%  -33.08%  (p=0.000 n=9+10)
Chain/chain-14/Explore-4                    1.71ms ±12%    1.17ms ± 7%  -31.54%  (p=0.000 n=9+9)
Chain/chain-13/Explore-4                    1.49ms ±34%    1.04ms ±26%  -30.47%  (p=0.000 n=10+9)
Chain/chain-11/Explore-4                    1.01ms ±17%    0.75ms ± 8%  -25.58%  (p=0.000 n=9+9)
Chain/chain-12/Explore-4                    1.20ms ± 9%    0.90ms ± 9%  -24.87%  (p=0.000 n=10+10)
Chain/chain-10/Explore-4                     836µs ± 8%     695µs ±21%  -16.83%  (p=0.001 n=10+10)
IndexConstraints/single-jumbo-span-100-4    1.49ms ± 9%    1.25ms ± 6%  -15.88%  (p=0.000 n=9+10)
IndexConstraints/single-jumbo-span-10-4     21.2µs ± 5%    18.1µs ± 4%  -14.88%  (p=0.000 n=10+8)
Chain/chain-8/Explore-4                      538µs ± 7%     486µs ±10%   -9.70%  (p=0.000 n=9+10)
Chain/chain-9/Explore-4                      700µs ± 9%     634µs ± 3%   -9.34%  (p=0.000 n=10+7)
Chain/chain-7/Explore-4                      445µs ±12%     406µs ± 8%   -8.77%  (p=0.004 n=9+9)
FKInsert/MultiRowMultiParent/None-4         1.04ms ±11%    0.97ms ± 8%   -6.68%  (p=0.046 n=9+8)
IndexConstraints/many-columns-4             5.95µs ± 3%    5.74µs ± 3%   -3.48%  (p=0.007 n=8+8)
IndexConstraints/range-2d-4                 3.43µs ± 5%    3.33µs ± 5%   -3.09%  (p=0.050 n=8+8)
Phases/kv-read-const/Normalize-4            89.9ns ±11%    97.6ns ±15%   +8.61%  (p=0.034 n=10+10)
Phases/kv-read-const/Explore-4               103ns ±16%     114ns ±18%  +10.97%  (p=0.011 n=10+10)
ColSet/colset-4                              173ns ± 5%     193ns ± 4%  +11.64%  (p=0.000 n=8+9)

name                                      old alloc/op   new alloc/op   delta
Chain/chain-19/Explore-4                    2.08MB ± 0%    0.77MB ± 0%  -63.07%  (p=0.000 n=10+9)
Chain/chain-18/Explore-4                    1.75MB ± 0%    0.70MB ± 0%  -59.94%  (p=0.000 n=9+10)
Chain/chain-17/Explore-4                    1.47MB ± 0%    0.64MB ± 0%  -56.63%  (p=0.000 n=9+10)
Chain/chain-16/Explore-4                    1.23MB ± 0%    0.58MB ± 0%  -52.94%  (p=0.000 n=10+10)
Chain/chain-15/Explore-4                    1.01MB ± 0%    0.50MB ± 0%  -49.85%  (p=0.000 n=9+10)
Chain/chain-14/Explore-4                     834kB ± 0%     456kB ± 0%  -45.32%  (p=0.000 n=10+10)
Chain/chain-13/Explore-4                     634kB ± 0%     355kB ± 0%  -43.94%  (p=0.000 n=10+10)
Chain/chain-12/Explore-4                     515kB ± 0%     314kB ± 0%  -38.95%  (p=0.000 n=10+10)
Chain/chain-11/Explore-4                     407kB ± 0%     266kB ± 0%  -34.49%  (p=0.000 n=10+10)
Chain/chain-10/Explore-4                     329kB ± 0%     234kB ± 0%  -28.74%  (p=0.000 n=9+10)
Chain/chain-9/Explore-4                      263kB ± 0%     202kB ± 0%  -23.24%  (p=0.000 n=10+10)
Chain/chain-8/Explore-4                      187kB ± 0%     150kB ± 0%  -20.19%  (p=0.000 n=8+10)
Chain/chain-7/Explore-4                      148kB ± 0%     126kB ± 0%  -14.76%  (p=0.000 n=10+10)
Chain/chain-6/Explore-4                      114kB ± 0%     103kB ± 0%  -10.14%  (p=0.000 n=9+10)
Chain/chain-5/Explore-4                     82.6kB ± 0%    77.1kB ± 0%   -6.59%  (p=0.000 n=10+10)
Chain/chain-4/Explore-4                     58.1kB ± 0%    55.9kB ± 0%   -3.72%  (p=0.000 n=7+10)
Phases/tpcc-stock-level/Normalize-4         15.8kB ± 0%    15.3kB ± 0%   -3.04%  (p=0.000 n=10+10)
Phases/tpcc-stock-level/OptBuild-4          16.2kB ± 0%    15.7kB ± 0%   -2.97%  (p=0.000 n=10+10)
Chain/chain-3/Explore-4                     38.6kB ± 0%    37.9kB ± 0%   -1.66%  (p=0.000 n=10+9)
Phases/tpcc-stock-level/Explore-4           50.7kB ± 0%    50.2kB ± 0%   -0.95%  (p=0.000 n=9+10)
Phases/tpcc-stock-level/ExecBuild-4         51.6kB ± 0%    51.1kB ± 0%   -0.94%  (p=0.000 n=9+10)
EndToEnd/tpcc-stock-level/EndToEnd-4         138kB ± 0%     137kB ± 0%   -0.39%  (p=0.000 n=9+10)
Chain/chain-2/Explore-4                     21.9kB ± 0%    21.8kB ± 0%   -0.36%  (p=0.000 n=10+9)
EndToEnd/kv-read-no-prep/EndToEnd-4         27.9kB ± 0%    27.8kB ± 0%   -0.17%  (p=0.019 n=9+9)
FKInsert/SingleRow/None-4                   53.4kB ± 1%    53.6kB ± 1%   +0.49%  (p=0.019 n=10+10)

name                                      old allocs/op  new allocs/op  delta
Chain/chain-19/Explore-4                     4.64k ± 0%     2.52k ± 0%  -45.78%  (p=0.000 n=8+8)
Chain/chain-18/Explore-4                     4.16k ± 0%     2.36k ± 0%  -43.28%  (p=0.000 n=10+10)
Chain/chain-17/Explore-4                     3.72k ± 0%     2.21k ± 0%  -40.65%  (p=0.000 n=8+10)
Chain/chain-16/Explore-4                     3.31k ± 0%     2.05k ± 0%  -37.93%  (p=0.000 n=7+10)
Chain/chain-15/Explore-4                     2.93k ± 0%     1.90k ± 0%  -35.13%  (p=0.000 n=8+8)
Chain/chain-14/Explore-4                     2.59k ± 0%     1.75k ± 0%  -32.15%  (p=0.000 n=8+10)
Chain/chain-13/Explore-4                     2.25k ± 0%     1.58k ± 0%  -29.44%  (p=0.000 n=10+10)
Chain/chain-12/Explore-4                     1.96k ± 0%     1.44k ± 0%  -26.34%  (p=0.000 n=10+10)
Chain/chain-11/Explore-4                     1.70k ± 0%     1.30k ± 0%  -23.19%  (p=0.000 n=10+10)
Chain/chain-10/Explore-4                     1.46k ± 0%     1.17k ± 0%  -20.03%  (p=0.001 n=8+9)
Chain/chain-9/Explore-4                      1.25k ± 0%     1.04k ± 0%  -16.91%  (p=0.000 n=10+10)
Chain/chain-8/Explore-4                      1.04k ± 0%     0.89k ± 0%  -14.09%  (p=0.000 n=10+10)
Chain/chain-7/Explore-4                        859 ± 0%       763 ± 0%  -11.18%  (p=0.000 n=10+10)
Chain/chain-6/Explore-4                        697 ± 0%       638 ± 0%   -8.46%  (p=0.000 n=10+10)
Chain/chain-5/Explore-4                        548 ± 0%       515 ± 0%   -6.02%  (p=0.000 n=10+10)
Phases/tpcc-stock-level/Normalize-4           98.0 ± 0%      94.0 ± 0%   -4.08%  (p=0.000 n=10+10)
Chain/chain-4/Explore-4                        410 ± 0%       394 ± 0%   -4.02%  (p=0.000 n=9+10)
Phases/tpcc-stock-level/OptBuild-4             100 ± 0%        96 ± 0%   -4.00%  (p=0.000 n=10+10)
Chain/chain-3/Explore-4                        283 ± 0%       277 ± 0%   -2.12%  (p=0.000 n=10+10)
Phases/tpcc-stock-level/Explore-4              271 ± 0%       267 ± 0%   -1.48%  (p=0.000 n=10+10)
Phases/tpcc-stock-level/ExecBuild-4            283 ± 0%       279 ± 0%   -1.41%  (p=0.000 n=10+10)
Chain/chain-2/Explore-4                        155 ± 0%       154 ± 0%   -0.65%  (p=0.000 n=10+10)
EndToEnd/tpcc-stock-level/EndToEnd-4           729 ± 0%       725 ± 0%   -0.54%  (p=0.000 n=9+10)
FKInsert/MultiRowMultiParent/New-4           2.71k ± 0%     2.71k ± 0%   -0.09%  (p=0.003 n=10+9)
FKInsert/SingleRow/New-4                     1.05k ± 0%     1.05k ± 0%   -0.08%  (p=0.042 n=6+10)

@rytaft
Copy link
Copy Markdown
Collaborator Author

rytaft commented Dec 16, 2019

bors r+

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Dec 16, 2019

Build failed (retrying...)

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Dec 17, 2019

Build failed (retrying...)

Copy link
Copy Markdown
Member

@RaduBerinde RaduBerinde 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 (waiting on @justinj)

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Dec 17, 2019

Build failed

@awoods187
Copy link
Copy Markdown

Those tests are pretty stellar.

What do these tests do:

Phases/kv-read-const/Normalize-4            89.9ns ±11%    97.6ns ±15%   +8.61%  (p=0.034 n=10+10)
Phases/kv-read-const/Explore-4               103ns ±16%     114ns ±18%  +10.97%  (p=0.011 n=10+10)
ColSet/colset-4                              173ns ± 5%     193ns ± 4%  +11.64%  (p=0.00

Does KV need to signoff on any of this?

@RaduBerinde
Copy link
Copy Markdown
Member

No. "KV" refers to the type of workload (simple key-value table). Those tests show very large variations (e.g. ±18%), I wouldn't count on those differences meaning something. In fact, none of those tests are affected by this change (there are no joins).

On a more general note, I don't think it's useful to arbitrarily discuss benchmarks on PRs. We (meaning the PR author as well as the teammates reviewing it) have been using our best judgement on when we should look at benchmarks (based on our knowledge of the code) and I think we should continue to do that. One can reasonably ask about benchmarks on almost any given PR, and yet I don't think it's reasonable to spend time on them on every PR.

@rytaft
Copy link
Copy Markdown
Collaborator Author

rytaft commented Dec 17, 2019

Yea, I'm not too worried about the tests that got slightly worse due to the large variation. The allocation benchmarks show much less variation than the time benchmarks, and those are uniformly good. (And as Radu mentioned, I'm pretty confident that none of my code changes add much overhead.)

bors r+

craig bot pushed a commit that referenced this pull request Dec 17, 2019
43194: opt: use transitive equalities to infer filters r=rytaft a=rytaft

Previously, the optimizer was not inferring all possible filters
based on equality conditions. For example, consider a query such
as:
```
SELECT * FROM t
JOIN u ON t.a = u.a
JOIN v ON u.a = v.a
JOIN w ON v.a = w.a
WHERE t.a = 5;
```
Ideally, the optimizer should infer additional filter conditions
`u.a = 5 AND v.a = 5 AND w.a = 5` based on the equality conditions.
However, this was not occurring because the optimizer only considered
equality conditions that were at the same level in the query tree as the
filter to be mapped. Now the optimizer also considers equality conditions
that are further down in the tree, so that additional filters can
be inferred based on transitive equalities.

Informs #43039

Release note (performance improvement): The optimizer can now infer
additional filter conditions in some cases based on transitive equalities
between columns.

43218: backupccl: stop swallowing error in restoreResumer.OnFailOrCancel() r=ajwerner a=ajwerner

In `restoreResumer.OnFailOrCancel()` we'd return nil when encountering a
non-nil error in a call to `sqlbase.RemovePublicTableNamespaceEntry()`.
Error handling in `jobs.Resumer.OnFailOrCancel()` is a tricky proposition but
this behavior is certainly wrong.

Release note: None

Co-authored-by: Rebecca Taft <becca@cockroachlabs.com>
Co-authored-by: Andrew Werner <ajwerner@cockroachlabs.com>
@awoods187
Copy link
Copy Markdown

Awesome--excited about this change

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Dec 17, 2019

Build succeeded

@craig craig bot merged commit 0daebf1 into cockroachdb:master Dec 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants