sql: optimize point lookups on column families#30744
sql: optimize point lookups on column families#30744craig[bot] merged 1 commit intocockroachdb:masterfrom
Conversation
|
I'm going to add unit tests and additional logic tests, but the implementation is ready for a look if you're curious. |
jordanlewis
left a comment
There was a problem hiding this comment.
The implementation looks great - very clean. The logic test failures are kind of weird. Why would this one have ended up looking at more spans than before?
testdata/select:578: SELECT message FROM [SHOW KV TRACE FOR SESSION]
WHERE message LIKE 'fetched:%' OR message LIKE 'output row%'
expected:
fetched: /dt/primary/'2015-08-25 04:45:45.53453+00:00'/b -> '2015-08-25'
fetched: /dt/primary/'2015-08-25 04:45:45.53453+00:00'/c -> '2h45m2s234ms'
output row: ['2015-08-25 04:45:45.53453+00:00' '2015-08-25' '2h45m2s234ms']
but found (query options: "") :
fetched: /dt/primary/'2015-08-25 04:45:45.53453+00:00' -> NULL
fetched: /dt/primary/'2015-08-25 04:45:45.53453+00:00'/b -> '2015-08-25'
fetched: /dt/primary/'2015-08-25 04:45:45.53453+00:00'/c -> '2h45m2s234ms'
output row: ['2015-08-25 04:45:45.53453+00:00' '2015-08-25' '2h45m2s234ms']
Reviewed 7 of 7 files at r1.
Reviewable status:complete! 0 of 0 LGTMs obtained
pkg/sql/opt_index_selection.go, line 687 at r1 (raw file):
// least one non-nullable column in the needed column families, we can // potentially omit the primary family, since the primary keys are encoded // in all families.
Cool idea!
solongordon
left a comment
There was a problem hiding this comment.
Huh, I actually removed that first line from the expected output because that's the result I was seeing locally (and it seemed reasonable). But looks like Teamcity is still seeing the old result. I'll check it out. Also will look into why zone config tests are unhappy.
Reviewable status:
complete! 0 of 0 LGTMs obtained
|
Looks like this breaks the delete fast path, since that only deletes the spans from the delete node's underlying scan node. I'm looking into what the proper fix for that should be but open to suggestions. |
RaduBerinde
left a comment
There was a problem hiding this comment.
Reviewable status:
complete! 0 of 0 LGTMs obtained
pkg/sql/opt_index_selection.go, line 603 at r1 (raw file):
// non-adjacent column families should be scanned. func spansFromConstraintSpan( tableDesc *sqlbase.TableDescriptor,
It's better if this function takes an input Spans and appends to it, or we end up allocating a temporary Spans for each logical spans
pkg/sql/opt_index_selection.go, line 687 at r1 (raw file):
Previously, jordanlewis (Jordan Lewis) wrote…
Cool idea!
Except for composite datums :)
solongordon
left a comment
There was a problem hiding this comment.
Reviewable status:
complete! 0 of 0 LGTMs obtained
pkg/sql/opt_index_selection.go, line 603 at r1 (raw file):
Previously, RaduBerinde wrote…
It's better if this function takes an input
Spansand appends to it, or we end up allocating a temporary Spans for each logical spans
Done
pkg/sql/opt_index_selection.go, line 687 at r1 (raw file):
Previously, RaduBerinde wrote…
Except for composite datums :)
Aha, good point. Adding that to the comment since I will surely forget about that exception.
b0468a1 to
8f1f62c
Compare
solongordon
left a comment
There was a problem hiding this comment.
OK, I think I fixed the deletion issues. I don't love the solution, but it's the least hacky approach I could find. I'm disabling this optimization if the spans might be used for the delete fast path. The annoying part was that this requires the scanNode to be aware that it is the source for a delete. Best way I could find to do this was to set a flag during plan expansion. I'm certainly open to other suggestions.
I still intend to add more testing.
Reviewable status:
complete! 0 of 0 LGTMs obtained
solongordon
left a comment
There was a problem hiding this comment.
Reviewable status:
complete! 0 of 0 LGTMs obtained
pkg/sql/opt_index_selection.go, line 687 at r1 (raw file):
Previously, solongordon (Solon) wrote…
Aha, good point. Adding that to the comment since I will surely forget about that exception.
Done.
jordanlewis
left a comment
There was a problem hiding this comment.
Reviewable status:
complete! 0 of 0 LGTMs obtained
pkg/sql/expand_plan.go, line 126 at r2 (raw file):
// If the source of the delete is a scan node (optionally with a render on // top), mark it as such. Note that this parallels the logic in // canDeleteFast.
To minimize this hacky-ness, I would make sure to add a corresponding comment to canDeleteFast. If that implementation changes and this one doesn't, what happens?
Also, I'm not sure how feasible this is, but can you have the deleteNode declare all columns as required? Or does this mess other things up?
solongordon
left a comment
There was a problem hiding this comment.
Reviewable status:
complete! 0 of 0 LGTMs obtained
pkg/sql/expand_plan.go, line 126 at r2 (raw file):
Previously, jordanlewis (Jordan Lewis) wrote…
To minimize this hacky-ness, I would make sure to add a corresponding comment to canDeleteFast. If that implementation changes and this one doesn't, what happens?
Also, I'm not sure how feasible this is, but can you have the deleteNode declare all columns as required? Or does this mess other things up?
Yes, will do.
I fooled around with the required columns approach but didn't have much luck. From the perspective of the delete node it's already marking all columns as needed:
cockroach/pkg/sql/opt_needed.go
Lines 212 to 213 in 4e60d58
but in many cases this is only a subset of the columns because there is a projection between it and the scan node. It's probably possible to make this work but it felt like I was heading down a hackier path than the scanNode flag approach.
9edaa87 to
176c139
Compare
jordanlewis
left a comment
There was a problem hiding this comment.
LGTM. Can you add a couple of EXPLAIN logic tests to ensure we don't regress?
176c139 to
a8980f6
Compare
| PRIMARY KEY (a, b), | ||
| FAMILY (a, b), | ||
| FAMILY (c), | ||
| FAMILY (d) |
There was a problem hiding this comment.
Nice tests. The main one I was thinking of that I don't see here is a test that two adjacent non-primary families get coalesced into a single span. I'm sure it works today, since similar logic triggers for the primary-adjacent families, but this seems like a case that might regress as code changes.
| · table t3@primary · · | ||
|
|
||
| # ------------------------------------------------------------------------------ | ||
| # These tests are for the point lookup optimization, which applies to SELECTs |
There was a problem hiding this comment.
Might as well throw a quick explanation of the optimization in here.
solongordon
left a comment
There was a problem hiding this comment.
Reviewable status:
complete! 0 of 0 LGTMs obtained
pkg/sql/opt/exec/execbuilder/testdata/select_index, line 1341 at r4 (raw file):
Previously, jordanlewis (Jordan Lewis) wrote…
Might as well throw a quick explanation of the optimization in here.
Done.
pkg/sql/opt/exec/execbuilder/testdata/select_index, line 1353 at r4 (raw file):
Previously, jordanlewis (Jordan Lewis) wrote…
Nice tests. The main one I was thinking of that I don't see here is a test that two adjacent non-primary families get coalesced into a single span. I'm sure it works today, since similar logic triggers for the primary-adjacent families, but this seems like a case that might regress as code changes.
Good idea, done.
For tables with multiple column families, point lookups will now only scan column families which contain the needed columns. Previously we would scan the entire row. This optimization allows for faster lookups and, perhaps more importantly, reduces contention between operations on the same row but disjoint column families. Fixes cockroachdb#18168 Release note: None
a8980f6 to
ae97046
Compare
|
bors r+ |
30744: sql: optimize point lookups on column families r=solongordon a=solongordon For tables with multiple column families, point lookups will now only scan column families which contain the needed columns. Previously we would scan the entire row. This optimization allows for faster lookups and, perhaps more importantly, reduces contention between operations on the same row but disjoint column families. Fixes #18168 Release note: None Co-authored-by: Solon Gordon <solon@cockroachlabs.com>
Build succeeded |
|
Not sure this may want a backport? |
|
@nvanbenschoten and I discussed a backport and decided it was too risky for this late in the stability period. |
For tables with multiple column families, point lookups will now only
scan column families which contain the needed columns. Previously we
would scan the entire row. This optimization allows for faster lookups
and, perhaps more importantly, reduces contention between operations on
the same row but disjoint column families.
Fixes #18168
Release note: None