MariaDB:group_concat 子查询失败
MariaDB: group_concat with subquery failing
在 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 这听起来很相关,但我真的不明白他们在说什么,更重要的是,我应该怎么做。
这是一个错误,显然它与您发现的那个不太一样(因为提到的错误报告中的测试用例在 10.2.8 上运行正常,而您的确实不行) .请随时在 MariaDB JIRA.
报告新的
与此同时,我认为您应该可以通过设置
来解决这个问题
optimizer_switch=orderby_uses_equalities=off
在你的 cnf 文件中。这是一个新启用的优化,显然不是完美的。
更新:该错误现在报告为 https://jira.mariadb.org/browse/MDEV-13694
解决方法 这不会回答为什么会有差异,但您应该将 DISTINCT
添加到 GROUP_CONCAT
.
"why" 答案可能在优化器中根深蒂固。自 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
。
需要索引 这 "covering index" 会加快速度:INDEX(ActionTypeID, PersonID)
.
在 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 这听起来很相关,但我真的不明白他们在说什么,更重要的是,我应该怎么做。
这是一个错误,显然它与您发现的那个不太一样(因为提到的错误报告中的测试用例在 10.2.8 上运行正常,而您的确实不行) .请随时在 MariaDB JIRA.
报告新的与此同时,我认为您应该可以通过设置
来解决这个问题optimizer_switch=orderby_uses_equalities=off
在你的 cnf 文件中。这是一个新启用的优化,显然不是完美的。
更新:该错误现在报告为 https://jira.mariadb.org/browse/MDEV-13694
解决方法 这不会回答为什么会有差异,但您应该将 DISTINCT
添加到 GROUP_CONCAT
.
"why" 答案可能在优化器中根深蒂固。自 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
。
需要索引 这 "covering index" 会加快速度:INDEX(ActionTypeID, PersonID)
.