-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Add option to force join order for segment queries #21636
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine, I'm a bit nervous about there being no unit tests though for addJoinPrefixHintToQuery
Because this will be a opt-in piece of code maybe you could just add one test for this part:
$generalConfig = Config::getInstance()->General;
if (empty($generalConfig['enable_segment_first_table_join_prefix']) || $generalConfig['enable_segment_first_table_join_prefix'] != "1") {
return $sql;
}
To make sure that the opt-in part is at least working
Code change looks good, just a question — would the hint use the actual table name or the aliased name (if there's an alias used)? |
@michalkleiner The hint uses the alias if the table has one:
It's a bit confusing here because the table alias we use is the same as the table name! |
I've updated the PR:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments for possible improvements. Besides that the changes look good to me 👍
core/DataAccess/LogAggregator.php
Outdated
$generalConfig = Config::getInstance()->General; | ||
if (!empty($generalConfig['enable_first_table_join_prefix']) && $generalConfig['enable_first_table_join_prefix'] == "1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be simplified by using GeneralConfig::getConfigValue('enable_first_table_join_prefix')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now using the new DatabaseConfig::getConfigValue()
method 👍
core/DataAccess/LogAggregator.php
Outdated
$generalConfig = Config::getInstance()->General; | ||
if (!empty($generalConfig['enable_segment_first_table_join_prefix']) && $generalConfig['enable_segment_first_table_join_prefix'] == "1") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can be simplified using GeneralConfig
as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above.
@@ -341,6 +341,71 @@ public function test_getSegmentTmpTableNameWithLongPrefix() | |||
$this->assertEquals('logtmpsegmentcc2efa0acbd5f209', $this->logAggregator->getSegmentTmpTableName()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could maybe be worth to add a test that uses the new join feature as well as max execution time hint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved the query generation code from queryVisitsByDimension
to a new sub-method getQueryByDimensionSql
to make it easier to test the generated sql. I've then added a new test to check the expected visits by dimension query with an origin hint, join prefix hint and a max execution time hint.
config/global.ini.php
Outdated
|
||
; Add a query hint for the order of the first table for all log table queries in MySQL. | ||
enable_first_table_join_prefix = 0 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was wondering if this would make more sense to be part of the DB or DbReader config. As it's more related to database than general config. But don't have a strong opinion here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that probably makes the most sense 👍
I've moved the settings to the [database] section, as part of this I've made the GeneralConfig
class a bit easier to extend and added a new descendant class DatabaseConfig
so we can easily get settings from the [database]
section in the same way as we already do for [General]
…atabaseConfig class to retrieve [database] settings
…queryVisitByDimension to allow sql testing, added new test
@bx80 I like the new DatabaseConfig class approach, but may I suggest that both the |
@michalkleiner Yeah, I thought about doing that but was trying to limit the rework scope, in retrospect it should be quick to do and a better starting point for any other new descendants so I'll make the change now 👍 |
@sgiehl @michalkleiner @caddoo Thanks for all the feedback, this should be ready for a final review now 😃 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a minor formatting/text tweak that can be skipped for now.
Code changes look good, newly added tests are passing, although I haven't run the code locally to see the actual queries.
Co-authored-by: Michal Kleiner <michal@innocraft.com>
Co-authored-by: Michal Kleiner <michal@innocraft.com>
Co-authored-by: Michal Kleiner <michal@innocraft.com>
Description:
Fixes #21635
This PR adds two new config options:
When enabled the first option will cause a query hint to be added to segment selection queries which will suggest the join order of the first table and prevent the MySQL query planner from choosing a different starting table for the join plan.
The second option does the same but for all queries built using LogAggregator::GenerateQuery()
Before:
After:
Notes:
This only applies to queries used to build segment temporary tables, it is not currently applied to any other queries.queryVisitsByDimension()
andcreateSegmentTable()
methods have both had their sql generation code moved to sub-methods to allow easier testing of the query sql.Review