在MySQL 5.6.34(我的新开发服务器)和MariaDB 10.2.8(我的新生产服务器,我认为我最终在今天部署代码 - 叹息!)中使用完全相同的数据库结构和数据,MySQL是工作和MariaDB不是。这是在MySQL 5.0.95上运行良好多年的代码。我已将查询简化为显示问题的最小示例 - 似乎GROUP_CONCAT()
和子查询不混合。这是查询:
SELECT person.PersonID,
GROUP_CONCAT(CategoryID ORDER BY CategoryID SEPARATOR ',') AS categories
FROM person LEFT JOIN percat ON person.PersonID=percat.PersonID
WHERE person.PersonID IN (SELECT PersonID FROM action WHERE ActionTypeID=3)
GROUP BY person.PersonID
这是截图的合成图像,显示了所涉及的所有三个表的结构:
在MySQL上,它工作正常,因为它已经工作了多年。结果如下EXPLAIN
:
这是我在MariaDB上获得的疯狂结果:
我不知道数据库引擎的内部工作方式是否足以跟随EXPLAIN
,但我认为线索存在于某处。我发现this bug report听起来很相关,但我真的不明白他们对此有什么看法,更重要的是,我应该怎么做。
答案 0 :(得分:2)
这是一个错误,显然它与您找到的错误不完全相同(因为上面提到的错误报告中的测试用例在10.2.8上可以正常工作,而您的确实没有)。请随时在MariaDB JIRA报告一个新的。
与此同时,我认为您应该可以通过设置
来解决这个问题optimizer_switch=orderby_uses_equalities=off
你的cnf文件中的。这是一个新启用的优化,显然不是完美的。
更新:该错误现在报告为https://jira.mariadb.org/browse/MDEV-13694
答案 1 :(得分:0)
解决方法这不会回答原因存在差异的原因,但您应该将DISTINCT
添加到GROUP_CONCAT
。
“为什么”可能答案非常深植于优化器中。自5.0以来发生了很多变化。 5.6有很多新代码;与此同时,MariaDB正在分成10.0。在这种分叉中,优化器显着分歧。 10.2进一步向前推进,但未必优化此类查询。
改进查询可以对查询执行多项操作。有些人可能会加快速度:
SELECT p.PersonID,
( SELECT GROUP_CONCAT(pc.CategoryID
ORDER BY CategoryID SEPARATOR ',')
FROM percat
WHERE PersonID = p.PersonID
) AS categories
FROM person
JOIN action AS a ON p.PersonID = a.PersonID
WHERE ActionTypeID = 3
GROUP BY p.PersonID
转换LEFT JOIN
可能会减少GROUP BY
的负担。可能会移除GROUP BY
。
由于PRIMARY KEY(PersonID, CategoryID)
,因此不需要DISTINCT
。
需要的索引这个“覆盖索引”可以加快速度:INDEX(ActionTypeID, PersonID)
。