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

[rowexec] custom rowexec #8072

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open

[rowexec] custom rowexec #8072

wants to merge 35 commits into from

Conversation

max-hoffman
Copy link
Contributor

@max-hoffman max-hoffman commented Jun 25, 2024

This PR adds custom Dolt execution operators for lookup joins. When building an execution plan, we try to replace joinIter with a Dolt equivalent that inlines the key building and map get. This is a lot faster than repeatedly building the secondary iterator and materializing sql.Rows in-between lookups.

The main downside is that this PR hoists filters in join children to after materializing lookup join rows.

This brings index_join from 5.18 ms/query to 2.64 ms/q, which will be about 2.0x MySQL's latency.

This PR falls short of some aspiration goals:

  • We hoist table filters until after the final join row is built because we don't have a way to call scalar expressions on val.Tuple yet. There are edge case queries that might be dramatically slower because of this. To fix this, we could need to convert sql.Expression filters into a format that we could execute on val.Tuple KV pairs.
  • We do not yet try to to optimize consecutive lookup joins. I'm not sure if a materialization block would be better represented iteratively or recursively beyond a simple string of lookups. A lot of interfaces and indexing considerations to think about there.

Safety comments:

  • we fallback to GMS when lookup source/dest keys are not prolly.Encoding compatible
  • the source iterators are the same as what we used before, but without projection mapping to sql.Rows. The keyless iterator required a change to return duplicate rows at the KV layer (vs the sql layer).
  • the secondary iterators are a generalization of what we currently use, but return KV pairs instead of rows
  • projection mapping is the same but generalized to merge an arbitrary list of KV pairs after the join

There are extra tests here: dolthub/go-mysql-server#2593

@max-hoffman
Copy link
Contributor Author

#benchmark

Copy link

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

test_name from_latency_p95 to_latency_p95 is_faster
tpcc-scale-factor-1 73.13 89.16 0
test_name server_name server_version tps test_name server_name server_version tps is_faster
tpcc-scale-factor-1 dolt f7abadf 32.99 tpcc-scale-factor-1 dolt c531bce 13.52 1

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

read_tests from_latency_median to_latency_median is_faster
covering_index_scan 2.76 2.81 0
groupby_scan 17.32 17.32 0
index_join 5.28 2.61 1
index_join_scan 2.57 2.57 0
index_scan 53.85 54.83 0
oltp_point_select 0.46 0.46 0
oltp_read_only 7.56 7.7 0
select_random_points 0.77 0.77 0
select_random_ranges 0.92 0.92 0
table_scan 54.83 55.82 0
types_table_scan 142.39 142.39 0
write_tests from_latency_median to_latency_median is_faster
oltp_delete_insert 6.09 6.09 0
oltp_insert 3.02 3.02 0
oltp_read_write 14.21 14.21 0
oltp_update_index 3.13 3.07 0
oltp_update_non_index 3.02 3.02 0
oltp_write_only 6.43 6.43 0
types_delete_insert 6.67 6.67 0

Copy link

Additional work is required for integration with DoltgreSQL.

@max-hoffman
Copy link
Contributor Author

#benchmark

Copy link

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

test_name from_latency_p95 to_latency_p95 is_faster
tpcc-scale-factor-1 74.46 78.6 0
test_name server_name server_version tps test_name server_name server_version tps is_faster
tpcc-scale-factor-1 dolt 0c4b3f9 32.94 tpcc-scale-factor-1 dolt ef8cc8b 32.89 0

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

read_tests from_latency_median to_latency_median is_faster
covering_index_scan 2.86 2.86 0
groupby_scan 17.01 17.32 0
index_join 5.28 2.66 1
index_join_scan 2.52 2.57 0
index_scan 53.85 53.85 0
oltp_point_select 0.44 0.46 0
oltp_read_only 7.43 7.56 0
select_random_points 0.73 0.74 0
select_random_ranges 0.87 0.89 0
table_scan 54.83 54.83 0
types_table_scan 139.85 142.39 0
write_tests from_latency_median to_latency_median is_faster
oltp_delete_insert 6.09 6.09 0
oltp_insert 2.97 3.02 0
oltp_read_write 13.7 13.95 0
oltp_update_index 3.07 3.07 0
oltp_update_non_index 3.02 3.02 0
oltp_write_only 6.32 6.43 0
types_delete_insert 6.55 6.67 0

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

comparing_percentages
100.000000 to 100.000000
version result total
c50e5b8 ok 5937457
version total_tests
c50e5b8 5937457
correctness_percentage
100.0

@coffeegoddd
Copy link
Contributor

@coffeegoddd DOLT

comparing_percentages
100.000000 to 100.000000
version result total
921e758 ok 5937457
version total_tests
921e758 5937457
correctness_percentage
100.0

@max-hoffman
Copy link
Contributor Author

#benchmark

Copy link

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

comparing_percentages
100.000000 to 100.000000
version result total
ef3a0cf ok 5937457
version total_tests
ef3a0cf 5937457
correctness_percentage
100.0

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

comparing_percentages
100.000000 to 100.000000
version result total
f5ab6be ok 5937457
version total_tests
f5ab6be 5937457
correctness_percentage
100.0

@coffeegoddd
Copy link
Contributor

@coffeegoddd DOLT

comparing_percentages
100.000000 to 100.000000
version result total
327ce5e ok 5937457
version total_tests
327ce5e 5937457
correctness_percentage
100.0

@max-hoffman
Copy link
Contributor Author

#benchmark

Copy link

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

test_name from_latency_p95 to_latency_p95 is_faster
tpcc-scale-factor-1 74.46 77.19 0
test_name server_name server_version tps test_name server_name server_version tps is_faster
tpcc-scale-factor-1 dolt 3745baa 32.69 tpcc-scale-factor-1 dolt 327ce5e 32.51 0

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

read_tests from_latency_median to_latency_median is_faster
covering_index_scan 3.02 3.02 0
groupby_scan 17.32 17.32 0
index_join 5.28 5.28 0
index_join_scan 2.61 2.61 0
index_scan 55.82 55.82 0
oltp_point_select 0.46 0.46 0
oltp_read_only 7.84 7.84 0
select_random_points 0.75 0.75 0
select_random_ranges 0.9 0.9 0
table_scan 56.84 57.87 0
types_table_scan 147.61 147.61 0
write_tests from_latency_median to_latency_median is_faster
oltp_delete_insert 6.09 6.09 0
oltp_insert 3.02 3.02 0
oltp_read_write 14.21 14.21 0
oltp_update_index 3.13 3.13 0
oltp_update_non_index 3.02 3.02 0
oltp_write_only 6.43 6.43 0
types_delete_insert 6.67 6.67 0

@max-hoffman
Copy link
Contributor Author

Trying to figure out how to add a unit test for making sure we do the optimization when we expect. Surprisingly easy to accidentally disable.

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

comparing_percentages
100.000000 to 100.000000
version result total
ba424ee ok 5937457
version total_tests
ba424ee 5937457
correctness_percentage
100.0

@max-hoffman
Copy link
Contributor Author

#benchmark

Copy link

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

test_name from_latency_p95 to_latency_p95 is_faster
tpcc-scale-factor-1 75.82 75.82 0
test_name server_name server_version tps test_name server_name server_version tps is_faster
tpcc-scale-factor-1 dolt 3745baa 32.33 tpcc-scale-factor-1 dolt ba424ee 32.28 0

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

read_tests from_latency_median to_latency_median is_faster
covering_index_scan 3.02 3.02 0
groupby_scan 17.32 17.32 0
index_join 5.28 2.71 1
index_join_scan 2.61 2.61 0
index_scan 54.83 54.83 0
oltp_point_select 0.46 0.46 0
oltp_read_only 7.7 7.7 0
select_random_points 0.75 0.75 0
select_random_ranges 0.9 0.9 0
table_scan 56.84 56.84 0
types_table_scan 144.97 144.97 0
write_tests from_latency_median to_latency_median is_faster
oltp_delete_insert 5.99 5.99 0
oltp_insert 2.97 3.02 0
oltp_read_write 13.95 13.95 0
oltp_update_index 3.07 3.07 0
oltp_update_non_index 2.97 3.02 0
oltp_write_only 6.32 6.43 0
types_delete_insert 6.55 6.67 0

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

comparing_percentages
100.000000 to 100.000000
version result total
8a59480 ok 5937457
version total_tests
8a59480 5937457
correctness_percentage
100.0

@coffeegoddd
Copy link
Contributor

@coffeegoddd DOLT

comparing_percentages
100.000000 to 100.000000
version result total
bf6fdbb ok 5937457
version total_tests
bf6fdbb 5937457
correctness_percentage
100.0

@coffeegoddd
Copy link
Contributor

@max-hoffman DOLT

comparing_percentages
100.000000 to 100.000000
version result total
425b421 ok 5937457
version total_tests
425b421 5937457
correctness_percentage
100.0

@coffeegoddd
Copy link
Contributor

@coffeegoddd DOLT

comparing_percentages
100.000000 to 100.000000
version result total
cc67078 ok 5937457
version total_tests
cc67078 5937457
correctness_percentage
100.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants