与 mysql 5.6 相比,mariadb 10 的查询时间更长
Query takes longer with mariadb 10 vs mysql 5.6
我们最近将一个 PHP 网络应用程序迁移到了不同的主机。与此同时,数据库也成功复制到新的 mysql 服务器。数据库服务器的早期版本是 mysql5.6,新主机安装了 mariadb 10。下面是一个示例查询,在旧主机上大约需要 0.5 秒,而在使用 mariadb 的新主机上,大约需要 40 秒,这非常长。这么长的时间把托管服务器塞满了。
SELECT
IB.IndicatorId,
IB.IndicatorTitle,
IB.IndicatorCode,
IC.IndicatorCategoryName,
AA.Answer,
GROUP_CONCAT(AI.`Answer`) AS CombinedAnswers
FROM answer AS A
LEFT JOIN answers_answer AS AA ON AA.AnswerId = A.AnswerId
LEFT JOIN activity_sections_indicators AS ASI ON ASI.SectionIndicatorId = AA.SectionIndicatorId
LEFT JOIN indicators_bank AS IB ON IB.IndicatorId = ASI.IndicatorId
LEFT JOIN indicator_categories AS IC ON IC.IndicatorCategoryId = IB.IndicatorCategoryId
LEFT JOIN answers_items AS AI ON AI.AnswerAnswerId = AA.AnswerAnswerId
WHERE A.ProgramActivityId IN (103,104,105)
AND A.Code = 'Newsas263'
GROUP BY IB.IndicatorId
另外表的记录数如下
答案:5355
answers_answer : 845209
activity_sections_indicators : 2866
indicators_bank : 1175
indicator_categories : 17
answers_items : 934347
我的理解是,虽然查询也可以优化,但 mariadb 服务器配置中缺少一些东西。我有 VPS 并且可以更改 mariadb 的配置,但我不确定从这里可以做什么。
如果需要更多详细信息,请告诉我。非常感谢您在这方面的帮助。
MySQL 和 MariaDB 在 5.6 中有一些显着差异。很难发现具体的不同之处。
EXPLAIN SELECT ...
输出可能有帮助。
这些复合 and/or 覆盖索引可能对两台服务器都有帮助:
IB: INDEX(IndicatorId, IndicatorTitle, IndicatorCode, IndicatorCategoryId)
IC: INDEX(IndicatorCategoryId, IndicatorCategoryName)
AA: INDEX(AnswerId, Answer, SectionIndicatorId, AnswerAnswerId)
AI: INDEX(AnswerAnswerId, Answer)
A: INDEX(Code, ProgramActivityId, AnswerId)
ASI: INDEX(SectionIndicatorId, IndicatorId)
添加复合索引时,删除具有相同前导列的索引。
也就是说,当你同时拥有INDEX(a)和INDEX(a,b)时,把前者扔掉。
“A”上的索引可能是最重要的。
是否有任何表格“many-to-many”?
哪个版本的 MariaDB?已经有 10.0 到 10.7。
我能够解决问题。
感谢“Ergest Basha”、“Markus Zeller”和“Rick James”的recommendation/suggestion。
我运行关于查询的“解释Select ...”和“执行计划”有一些差异。我能够减轻这些差异,新服务器上的查询现在可以正常工作。
虽然我不能清楚地找出差异,但我只是重新复制了整个数据库,问题就解决了。
我们最近将一个 PHP 网络应用程序迁移到了不同的主机。与此同时,数据库也成功复制到新的 mysql 服务器。数据库服务器的早期版本是 mysql5.6,新主机安装了 mariadb 10。下面是一个示例查询,在旧主机上大约需要 0.5 秒,而在使用 mariadb 的新主机上,大约需要 40 秒,这非常长。这么长的时间把托管服务器塞满了。
SELECT
IB.IndicatorId,
IB.IndicatorTitle,
IB.IndicatorCode,
IC.IndicatorCategoryName,
AA.Answer,
GROUP_CONCAT(AI.`Answer`) AS CombinedAnswers
FROM answer AS A
LEFT JOIN answers_answer AS AA ON AA.AnswerId = A.AnswerId
LEFT JOIN activity_sections_indicators AS ASI ON ASI.SectionIndicatorId = AA.SectionIndicatorId
LEFT JOIN indicators_bank AS IB ON IB.IndicatorId = ASI.IndicatorId
LEFT JOIN indicator_categories AS IC ON IC.IndicatorCategoryId = IB.IndicatorCategoryId
LEFT JOIN answers_items AS AI ON AI.AnswerAnswerId = AA.AnswerAnswerId
WHERE A.ProgramActivityId IN (103,104,105)
AND A.Code = 'Newsas263'
GROUP BY IB.IndicatorId
另外表的记录数如下
答案:5355
answers_answer : 845209
activity_sections_indicators : 2866
indicators_bank : 1175
indicator_categories : 17
answers_items : 934347
我的理解是,虽然查询也可以优化,但 mariadb 服务器配置中缺少一些东西。我有 VPS 并且可以更改 mariadb 的配置,但我不确定从这里可以做什么。
如果需要更多详细信息,请告诉我。非常感谢您在这方面的帮助。
MySQL 和 MariaDB 在 5.6 中有一些显着差异。很难发现具体的不同之处。
EXPLAIN SELECT ...
输出可能有帮助。
这些复合 and/or 覆盖索引可能对两台服务器都有帮助:
IB: INDEX(IndicatorId, IndicatorTitle, IndicatorCode, IndicatorCategoryId)
IC: INDEX(IndicatorCategoryId, IndicatorCategoryName)
AA: INDEX(AnswerId, Answer, SectionIndicatorId, AnswerAnswerId)
AI: INDEX(AnswerAnswerId, Answer)
A: INDEX(Code, ProgramActivityId, AnswerId)
ASI: INDEX(SectionIndicatorId, IndicatorId)
添加复合索引时,删除具有相同前导列的索引。 也就是说,当你同时拥有INDEX(a)和INDEX(a,b)时,把前者扔掉。
“A”上的索引可能是最重要的。
是否有任何表格“many-to-many”?
哪个版本的 MariaDB?已经有 10.0 到 10.7。
我能够解决问题。
感谢“Ergest Basha”、“Markus Zeller”和“Rick James”的recommendation/suggestion。
我运行关于查询的“解释Select ...”和“执行计划”有一些差异。我能够减轻这些差异,新服务器上的查询现在可以正常工作。
虽然我不能清楚地找出差异,但我只是重新复制了整个数据库,问题就解决了。