-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Performance degradation in MySQLSchemaManager #5638
Comments
Thanks for reporting it as a new issue, @m-vo. The previous regression I referred to earlier is #5202. It was also caused by a schema introspection query using JOIN. The next steps would be:
Are you up making any of the above steps? |
Looking closer at #5195, I recall that the problem was caused specifically by the fact that we used the Could you check if replacing the right part in the |
Ah yes, that indeed does work as well. Without a fixed literal all tables get scanned ( I've had the problem on MariaDB 10.6 and also got it reported for MySQL 5.7. Judging by the last comment of your referenced MySQL bug, this should probably be fixed in MySQL 8. But it would be interesting if this is indeed the case. |
See #5639 for a first go. |
Please also see if this relates or is fixed by this issue: #5658 Cheers |
Seems like we are having the same issue with the method |
@brainformatik @morozov replied to me the other day that they are aware of that issue, not sure if there is already something open to fix it, or even if it is going to be fixed, check the reply here: #5658 (comment) |
@brainformatik thanks for confirming the issue. There's no dedicated issue open for it and it's not being actively worked. A pull request implementing the approach from #5639 is welcome. |
The same solution as for $sql .= <<<'SQL'
k.CONSTRAINT_NAME,
k.COLUMN_NAME,
k.REFERENCED_TABLE_NAME,
k.REFERENCED_COLUMN_NAME,
k.ORDINAL_POSITION /*!50116,
c.UPDATE_RULE,
c.DELETE_RULE */
FROM information_schema.key_column_usage k /*!50116
INNER JOIN information_schema.referential_constraints c
ON c.CONSTRAINT_NAME = k.CONSTRAINT_NAME
AND c.TABLE_NAME = k.TABLE_NAME */
SQL;
$conditions = ['k.TABLE_SCHEMA = ?'];
$params = [$databaseName];
if ($tableName !== null) {
$conditions[] = 'k.TABLE_NAME = ?';
$params[] = $tableName;
}
$conditions[] = 'k.REFERENCED_COLUMN_NAME IS NOT NULL';
$conditions[] = 'c.CONSTRAINT_SCHEMA = ?';
$params[] = $databaseName;
$sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY k.ORDINAL_POSITION'; The only problem with this would be, that if the executable comment is not applied so basically MySQL prior to 5.1.16, this will fail. |
I think this rework should work in any case, do you have any concerns by putting the database name directly in the query without using a $sql .= <<<'SQL'
k.CONSTRAINT_NAME,
k.COLUMN_NAME,
k.REFERENCED_TABLE_NAME,
k.REFERENCED_COLUMN_NAME,
k.ORDINAL_POSITION /*!50116,
c.UPDATE_RULE,
c.DELETE_RULE */
FROM information_schema.key_column_usage k /*!50116
INNER JOIN information_schema.referential_constraints c
ON c.CONSTRAINT_NAME = k.CONSTRAINT_NAME
AND c.TABLE_NAME = k.TABLE_NAME */
SQL;
$conditions = ['k.TABLE_SCHEMA = ?'];
$params = [$databaseName];
if ($tableName !== null) {
$conditions[] = 'k.TABLE_NAME = ?';
$params[] = $tableName;
}
$conditions[] = 'k.REFERENCED_COLUMN_NAME IS NOT NULL';
$constraintCondition = '/*!50116 AND c.CONSTRAINT_SCHEMA = "' . $databaseName . '" */';
$sql .= ' WHERE ' . implode(' AND ', $conditions) . $constraintCondition . ' ORDER BY k.ORDINAL_POSITION'; |
Please try using |
Tried it but it doesn't work. Seems like the parser ignores the |
That makes sense, the parser isn't aware of conditional comments. Please do it as originally proposed then, but make sure the database name is quoted before concatenating it with the query. |
Will do, but because I never contributed before, I'm not sure about best practice for quoting in this situation. I found the following methods that I can use:
Which one would you recommend to use in this case? Searched the repository and quoteStringLiteral is used a lot so this would be my guess. |
In this case, it's best to use |
FWIW, I was referring to the DBAL's SQL parser which is used only for named or list parameters, which isn't the case here. MySQL itself seems to work fine in this case:
Which parser were you referring to? |
It should be the PDO SQL parser that is causing trouble. If we use a placeholder, the tests pass on mysqli but fail on pdo_mysql. @brainformatik please see if #5667 works for you. |
Good to know. Yes it is working for us. Didn't have the time yesterday to prepare the PR properly. Thanks for quick solution! |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Bug Report
Summary
The changes from #5580 unfortunately severely degrade the performance for schema lookups with MySQL/MariaDB. The culprit is the newly added
JOIN
to filter out views inselectTableColumns()
. On my test setup the query took over 50x longer (~480ms compared to ~8ms) which results in quite a big hit in some applications.This seems like an odd DB performance problem. Interestingly, the following query (for the
foo
table) still is fast:So the workaround could be to replace the
JOIN
with a subquery:At least in my tests this solved the issue.
/cc @morozov
The text was updated successfully, but these errors were encountered: