catalog: pre-compute more column slices#74638
Conversation
postamar
commented
Jan 10, 2022
ajwerner
left a comment
There was a problem hiding this comment.
Reviewable status:
complete! 1 of 0 LGTMs obtained (waiting on @ajwerner and @postamar)
pkg/sql/row/fetcher.go, line 469 at r3 (raw file):
} for i, col := range columns { if col == nil || !col.Public() {
you could make this a nicer error in the case that the column is non-nil but non-public. Maybe ObjectNotInPrerequisiteState and provide the name of the column and/or the ID? I'm only pushing here because it appears this error shows up in the logic test for that funny case of trying to render a value for the conflict after a drop.
Code quote:
if col == nil || !col.Public() {
return nil, fmt.Errorf("column does not exist")
}These methods return the columns referenced in indexes as []catalog.Column slices. Release note: None
This complements the previous commit which added Index*Column methods to catalog.TableDescriptor. Release note: None
Calls to this function can now be replaced with recently-added IndexFullColumns and IndexFullColumnDirections method calls on the table descriptor. Release note: None
1a55f0d to
9c1f347
Compare
postamar
left a comment
There was a problem hiding this comment.
Thanks for the review. As always, by precomputing these column slices, we're trading off increased overhead vs. ad-hoc allocations. @nvanbenschoten The microbenchmarks for row and friends probably are worth running again after this merges. If allocations are too high, what needs to be done is not revert this but instead:
- use these precomputed slices more often, instead of calls to
FindColumnWithIDand friends which look up columns by ID one at a time; - altogether stop maintaining slices of column IDs in
row.tableInfoand friends.
A lot of this code and these data structures predate the catalog interfaces altogether and can almost certainly be streamlined. I've not done it because I don't know if it's worth doing. I estimate that doing this will take 3.6 days of work: not great, not terrible.
Reviewable status:
complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @ajwerner)
pkg/sql/row/fetcher.go, line 469 at r3 (raw file):
Previously, ajwerner wrote…
you could make this a nicer error in the case that the column is non-nil but non-public. Maybe
ObjectNotInPrerequisiteStateand provide the name of the column and/or the ID? I'm only pushing here because it appears this error shows up in the logic test for that funny case of trying to render a value for the conflict after a drop.
Done, although I've decided not to add a pgcode. This code would end up overriding any other, which is what ended up happening in the logic test.
Why not run them before this merges? |
|
It's that simple? I stupidly assumed it was going to be quite complicated. Sure, I'll do it! |
|
Yep! Microbenchmarks are nice and easy to run, measure, and iterate on (which is why #74443 is so great). Anything system-level that needs real VMs is more involved. |
|
I ran this microbenchmark and noticed that the perf regression was statistically significant, in some cases exceeding 2% more allocations. I pushed another commit which basically does the same pre-computations but reuses the same backing slice when possible. We now have (on my macbook) which, for what it's worth, I'm totally OK with. If this regression is a problem, then we should look into retrieving the table descriptor from the collections API instead of rebuilding it from the descriptor proto passed along in the spec. |
18e00bc to
0a39d55
Compare
|
I wonder if this will hurt given we end up constructing this with the table descriptor each time. This is all more fodder for using leased descriptors with distsql |
This commit removes IndexCompositeColumns (which wasn't actually used and is unlikely to ever be) and generates the indexColumnCache with less memory allocations. The current scheme is causing a statistically-significant performance regression. Release note: None
0a39d55 to
c3e81bc
Compare
|
Thanks for the reviews. I'll go ahead and merge this on the assumption that we'll use the leased descriptors at some point. In fact, I've already hacked something to that effect and the results are very promising. bors r+ |
|
Build succeeded: |
|
c.f. #74722 |
yuzefovich
left a comment
There was a problem hiding this comment.
Reviewable status:
complete! 0 of 0 LGTMs obtained (and 1 stale)
pkg/sql/colfetcher/cfetcher.go, line 447 at r6 (raw file):
needToDecodeDecimalKey := false for i, col := range fullColumns { if col == nil {
Saw this change when rebasing on top of master, and I'm confused by this block - when can col be nil here?
If the ID in the index key or keys uffix column ID slice refers to a table column which doesn't exist. |