have close costs. And indeed, the execution times for the two join orders (with ORDER BY ... LIMIT removed) are close.
TMP-TABLE-COST is a small fraction of join cost and doesn't make a difference (this seems to match the reality, too).
What does make a difference is short-cutting of execution due to LIMIT, but this is not taken into account.
Doing it in general case requires everything from MDEV-8306.
This MDEV is to have a fix for the join optimizer which adjusts the join order cost for cases with very small limit.
The new behavior is to be controlled by a setting.
If one runs OLTP-mostly workloads, enabling new behavior is an obvious choice.
Implementation
First, identify sort_by_table - the table that allows to use LIMIT short-cutting.
(Due to multiple equalities there can be multiple but we can assume it's just one table)
Do adjustment of cost/cardinality only for full join orders
Let's assume we've built a complete join order (ignoring ORDER BY ... LIMIT).
Having done that, we can compare join_output_size with the LIMIT number and see which "fraction" of join output we need and adjust the cost accordingly.
(An alternative to this: try to account for ORDER BY ...LIMIT earlier, while building join prefixes. We don't try to do this).
Adjusting join order cost and cardinality
Do it as follows:
1: If the join output is already produced in the required order, we can assume that $FRACT of join output will take $FRACT of the cost to produce. (Note: this is incorrect when using e.g. semi-join materialization or materialized derived tables. We ignore this fact for now).
Otherwise, we have two options:
2A: Change the access method for sort_by_table so that we do get rows in the desired order. After that, we can take a fraction of the cost like described above.
2B. Pass sort_by_table to filesort. We will need to spend the entire cost of reading sort_by_table but then we will be able to short-cut joining with subsequent tables.
Interplay with join optimizer pruning
So, we will adjust the costs only for complete join orders. The adjustment will reduce the cost and output-records.
Join pruning compares costs of prefix with full join order costs. Comparing un-adjusted costs with adjusted can produce wrong results.
we can prune un-adjusted prefix that will be adjusted
Hooking into the join optimizer - variant 1
First, run the join optimization as usual. This produces QUERY_PLAN1 and a tight upper bound of how many records the join would produce. (If it's smaller than LIMIT, short-cutting will probably not be beneficial).
Save join->best_read and join->best_positions.
Then, start the optimization again:
set join->best_read= DBL_MAX, Run the join optimization with first table=sort_by_table.
This produces QUERY_PLAN2 query plan that can take advantage of short-cutting.
Normally it's more expensive than QUERY_PLAN1.
Now, account for LIMIT short-cutting as specified in Adjusting join order's cost and cardinality section. This produces cost of QUERY_PLAN2-WITH-SHORTCUTTING. We can compare it with the cost of QUERY_PLAN1.
Hooking into the join optimizer - variant 2
Make the join optimizer first start with sort_table as the first table.
Once we have constructed a full join order, perform #rows/cost adjustments for LIMIT.
We can set the adjusted cost as join->best_read.
Then, proceed to run the join optimizer as usual.
Account for risks
QUERY_PLAN2-WITH-SHORTCUTTING is inherently more "risky". For example, if the join has a condition with selectivity=0.5 that the optimizer is not aware of, the actual cost of producing #LIMIT rows will be 1/0.5=2 times higher.
To account for this, we will add a multiplier, e.g. use QUERY_PLAN2-WITH-SHORTCUTTING only if promises a 100x speedup over QUERY_PLAN1.
psergei, was a 10.11 version of this implemented, tested and reviewed? There are conflicts when attempting to merge this to 10.11.
Marko Mäkelä
added a comment - psergei , was a 10.11 version of this implemented, tested and reviewed? There are conflicts when attempting to merge this to 10.11.
Yuchen Pei
added a comment - - edited marko and psergei : I also noticed some non-trivial conflict when trying to merge 10.6->10.11 today, mainly with the following commits:
commit b3c74bdc1f09b2b8babd7f2bd9d52df2749ddcc3
Author: Monty <monty@mariadb.org>
Date: Tue May 31 17:36:32 2022 +0300
Improve pruning in greedy_search by sorting tables during search
MDEV-28073 Slow query performance in MariaDB when using many tables
...
commit 8c2faad576d6a77314e92755a389de2c41e21242 (github/bb-10.10-optimizer-features)
Author: Sergei Petrunia <sergey@mariadb.com>
Date: Tue Jul 19 14:13:17 2022 +0300
MDEV-28929: Plan selection takes forever with MDEV-28852 ...
Part #2: Extend heuristic pruning to use multiple tables as the
"Model tables".
...
The nontrivial conflict is this one in sql_select.cc:
@@@ -10738,98 -10853,31 +11096,109 @@@ best_extension_by_limited_search(JOI
DBUG_EXECUTE("opt", print_plan(join, idx, record_count, read_time, read_time,
"part_plan"););
# [... 32 lines elided]
<<<<<<< A: HEAD
# [... 57 lines elided]
for (SORT_POSITION *pos= sort ; pos < sort_end ; pos++)
{
s= *pos->join_tab;
if (!(found_eq_ref_tables & s->table->map) &&
!check_interleaving_with_nj(s))
||||||| Ancestor
if ((allowed_tables & real_table_bit) &&
!(remaining_tables & s->dependent) &&
!check_interleaving_with_nj(s))
=======
if ((allowed_tables & real_table_bit) &&
!(remaining_tables & s->dependent) &&
!check_interleaving_with_nj(s) &&
join_limit_shortcut_allows_table(join, idx, s))
>>>>>>> B: Incoming
{
+ table_map real_table_bit= s->table->map;
double current_record_count, current_read_time;
double partial_join_cardinality;
- POSITION *position= join->positions + idx;
- POSITION loose_scan_pos;
+ POSITION *position= join->positions + idx, *loose_scan_pos;
Json_writer_object trace_one_table(thd);
Can you advise how to resolve it, psergei ?
I just pushed a merge of this to 10.11 using this for reference. There will be the following conflicts left for a merge to 11.2:
both modified: mysql-test/main/mysqld--help.result
both modified: mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
both modified: mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
both modified: sql/sql_select.cc
I didn’t check if there would be further conflicts for a merge to 11.4.
Marko Mäkelä
added a comment - I just pushed a merge of this to 10.11 using this for reference. There will be the following conflicts left for a merge to 11.2:
both modified: mysql-test/main/mysqld--help.result
both modified: mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
both modified: mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
both modified: sql/sql_select.cc
I didn’t check if there would be further conflicts for a merge to 11.4.
ycp, I see that you must have been trying to merge 10.6→10.11 in order to resolve conflicts that your recently pushed changes introduced. You should be able to continue with that now.
Marko Mäkelä
added a comment - ycp , I see that you must have been trying to merge 10.6→10.11 in order to resolve conflicts that your recently pushed changes introduced. You should be able to continue with that now.
People
Sergei Petrunia
Sergei Petrunia
Votes:
1Vote for this issue
Watchers:
10Start watching this issue
Dates
Created:
Updated:
Resolved:
Git Integration
Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.
{"report":{"fcp":1234.5999999046326,"ttfb":337.5,"pageVisibility":"visible","entityId":130284,"key":"jira.project.issue.view-issue","isInitial":true,"threshold":1000,"elementTimings":{},"userDeviceMemory":8,"userDeviceProcessors":64,"apdex":0.5,"journeyId":"258bc2f2-048d-43d3-94ce-89cb2ebf5489","navigationType":0,"readyForUser":1334.7000002861023,"redirectCount":0,"resourceLoadedEnd":2044.5999999046326,"resourceLoadedStart":343.30000019073486,"resourceTiming":[{"duration":412.2999997138977,"initiatorType":"link","name":"https://jira.mariadb.org/s/2c21342762a6a02add1c328bed317ffd-CDN/lu2cib/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/css/_super/batch.css","startTime":343.30000019073486,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":343.30000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":755.5999999046326,"responseStart":0,"secureConnectionStart":0},{"duration":412.40000009536743,"initiatorType":"link","name":"https://jira.mariadb.org/s/7ebd35e77e471bc30ff0eba799ebc151-CDN/lu2cib/820016/12ta74/494e4c556ecbb29f90a3d3b4f09cb99c/_/download/contextbatch/css/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true&whisper-enabled=true","startTime":343.5,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":343.5,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":755.9000000953674,"responseStart":0,"secureConnectionStart":0},{"duration":421.69999980926514,"initiatorType":"script","name":"https://jira.mariadb.org/s/0917945aaa57108d00c5076fea35e069-CDN/lu2cib/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/js/_super/batch.js?locale=en","startTime":343.7000002861023,"connectEnd":343.7000002861023,"connectStart":343.7000002861023,"domainLookupEnd":343.7000002861023,"domainLookupStart":343.7000002861023,"fetchStart":343.7000002861023,"redirectEnd":0,"redirectStart":0,"requestStart":343.7000002861023,"responseEnd":765.4000000953674,"responseStart":765.4000000953674,"secureConnectionStart":343.7000002861023},{"duration":456.69999980926514,"initiatorType":"script","name":"https://jira.mariadb.org/s/2d8175ec2fa4c816e8023260bd8c1786-CDN/lu2cib/820016/12ta74/494e4c556ecbb29f90a3d3b4f09cb99c/_/download/contextbatch/js/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&locale=en&slack-enabled=true&whisper-enabled=true","startTime":343.90000009536743,"connectEnd":343.90000009536743,"connectStart":343.90000009536743,"domainLookupEnd":343.90000009536743,"domainLookupStart":343.90000009536743,"fetchStart":343.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":343.90000009536743,"responseEnd":800.5999999046326,"responseStart":800.5999999046326,"secureConnectionStart":343.90000009536743},{"duration":460.69999980926514,"initiatorType":"script","name":"https://jira.mariadb.org/s/a9324d6758d385eb45c462685ad88f1d-CDN/lu2cib/820016/12ta74/c92c0caa9a024ae85b0ebdbed7fb4bd7/_/download/contextbatch/js/atl.global,-_super/batch.js?locale=en","startTime":344.2000002861023,"connectEnd":344.2000002861023,"connectStart":344.2000002861023,"domainLookupEnd":344.2000002861023,"domainLookupStart":344.2000002861023,"fetchStart":344.2000002861023,"redirectEnd":0,"redirectStart":0,"requestStart":344.2000002861023,"responseEnd":804.9000000953674,"responseStart":804.9000000953674,"secureConnectionStart":344.2000002861023},{"duration":460.90000009536743,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-en/jira.webresources:calendar-en.js","startTime":344.40000009536743,"connectEnd":344.40000009536743,"connectStart":344.40000009536743,"domainLookupEnd":344.40000009536743,"domainLookupStart":344.40000009536743,"fetchStart":344.40000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":344.40000009536743,"responseEnd":805.3000001907349,"responseStart":805.3000001907349,"secureConnectionStart":344.40000009536743},{"duration":461.1000003814697,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-localisation-moment/jira.webresources:calendar-localisation-moment.js","startTime":344.59999990463257,"connectEnd":344.59999990463257,"connectStart":344.59999990463257,"domainLookupEnd":344.59999990463257,"domainLookupStart":344.59999990463257,"fetchStart":344.59999990463257,"redirectEnd":0,"redirectStart":0,"requestStart":344.59999990463257,"responseEnd":805.7000002861023,"responseStart":805.7000002861023,"secureConnectionStart":344.59999990463257},{"duration":569.5999999046326,"initiatorType":"link","name":"https://jira.mariadb.org/s/b04b06a02d1959df322d9cded3aeecc1-CDN/lu2cib/820016/12ta74/a2ff6aa845ffc9a1d22fe23d9ee791fc/_/download/contextbatch/css/jira.global.look-and-feel,-_super/batch.css","startTime":344.80000019073486,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":344.80000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":914.4000000953674,"responseStart":0,"secureConnectionStart":0},{"duration":461.30000019073486,"initiatorType":"script","name":"https://jira.mariadb.org/rest/api/1.0/shortcuts/820016/47140b6e0a9bc2e4913da06536125810/shortcuts.js?context=issuenavigation&context=issueaction","startTime":344.90000009536743,"connectEnd":344.90000009536743,"connectStart":344.90000009536743,"domainLookupEnd":344.90000009536743,"domainLookupStart":344.90000009536743,"fetchStart":344.90000009536743,"redirectEnd":0,"redirectStart":0,"requestStart":344.90000009536743,"responseEnd":806.2000002861023,"responseStart":806.2000002861023,"secureConnectionStart":344.90000009536743},{"duration":569.4000000953674,"initiatorType":"link","name":"https://jira.mariadb.org/s/3ac36323ba5e4eb0af2aa7ac7211b4bb-CDN/lu2cib/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/css/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.css?jira.create.linked.issue=true","startTime":345.09999990463257,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":345.09999990463257,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":914.5,"responseStart":0,"secureConnectionStart":0},{"duration":461.5,"initiatorType":"script","name":"https://jira.mariadb.org/s/5d5e8fe91fbc506585e83ea3b62ccc4b-CDN/lu2cib/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/js/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.js?jira.create.linked.issue=true&locale=en","startTime":345.2000002861023,"connectEnd":345.2000002861023,"connectStart":345.2000002861023,"domainLookupEnd":345.2000002861023,"domainLookupStart":345.2000002861023,"fetchStart":345.2000002861023,"redirectEnd":0,"redirectStart":0,"requestStart":345.2000002861023,"responseEnd":806.7000002861023,"responseStart":806.7000002861023,"secureConnectionStart":345.2000002861023},{"duration":912.1999998092651,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-js/jira.webresources:bigpipe-js.js","startTime":346.30000019073486,"connectEnd":346.30000019073486,"connectStart":346.30000019073486,"domainLookupEnd":346.30000019073486,"domainLookupStart":346.30000019073486,"fetchStart":346.30000019073486,"redirectEnd":0,"redirectStart":0,"requestStart":346.30000019073486,"responseEnd":1258.5,"responseStart":1258.5,"secureConnectionStart":346.30000019073486},{"duration":1693.3999996185303,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2cib/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-init/jira.webresources:bigpipe-init.js","startTime":351.2000002861023,"connectEnd":351.2000002861023,"connectStart":351.2000002861023,"domainLookupEnd":351.2000002861023,"domainLookupStart":351.2000002861023,"fetchStart":351.2000002861023,"redirectEnd":0,"redirectStart":0,"requestStart":351.2000002861023,"responseEnd":2044.5999999046326,"responseStart":2044.5999999046326,"secureConnectionStart":351.2000002861023},{"duration":332.80000019073486,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":926.0999999046326,"connectEnd":926.0999999046326,"connectStart":926.0999999046326,"domainLookupEnd":926.0999999046326,"domainLookupStart":926.0999999046326,"fetchStart":926.0999999046326,"redirectEnd":0,"redirectStart":0,"requestStart":926.0999999046326,"responseEnd":1258.9000000953674,"responseStart":1258.9000000953674,"secureConnectionStart":926.0999999046326}],"fetchStart":0,"domainLookupStart":0,"domainLookupEnd":0,"connectStart":0,"connectEnd":0,"requestStart":151,"responseStart":337,"responseEnd":344,"domLoading":340,"domInteractive":2075,"domContentLoadedEventStart":2075,"domContentLoadedEventEnd":2123,"domComplete":2744,"loadEventStart":2744,"loadEventEnd":2745,"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)","marks":[{"name":"bigPipe.sidebar-id.start","time":2046.4000000953674},{"name":"bigPipe.sidebar-id.end","time":2047.0999999046326},{"name":"bigPipe.activity-panel-pipe-id.start","time":2047.3000001907349},{"name":"bigPipe.activity-panel-pipe-id.end","time":2050.5999999046326},{"name":"activityTabFullyLoaded","time":2140.800000190735}],"measures":[],"correlationId":"16120c61461ded","effectiveType":"4g","downlink":9.5,"rtt":0,"serverDuration":124,"dbReadsTimeInMs":14,"dbConnsTimeInMs":24,"applicationHash":"9d11dbea5f4be3d4cc21f03a88dd11d8c8687422","experiments":[]}}
psergei, was a 10.11 version of this implemented, tested and reviewed? There are conflicts when attempting to merge this to 10.11.