[英]Upgrade to mysql 5.7 from 5.5, MyISAM to InnoDB, LEFT JOIN and NULL issue
我最近将数据库从MySQL 5.5(带有MyISAM表)更新为MySQL 5.7 InnoDB表。 大多数事情都可以正常运行,但是有一些特定的查询却给出了奇怪的结果。
背景:建议首先得到批准,然后可以进行表决。 在建议被批准之前,该建议仅对建议者可见。
查询:
SELECT description, suggested_by, voted, votes
FROM shop_suggestions s
LEFT JOIN (SELECT suggestion, 1 AS voted FROM shop_suggestion_votes WHERE student = 60910) AS voted ON (voted.suggestion = s.id)
LEFT JOIN (SELECT suggestion, COUNT(student) AS votes FROM shop_suggestion_votes GROUP BY suggestion) AS votes ON (votes.suggestion = s.id)
WHERE approved > 0 OR suggested_by = 60910 ORDER BY votes
真正奇怪的是,当ORDER BY votes
部分存在时,投票值始终为1,而如果未选中该值,则在有人未投票的情况下其值为NULL。
此行为与升级之前的状态不同,在该情况下查询可以完美运行。 我假设某个地方存在某种逻辑错误,但我无法弄清楚。 任何帮助将不胜感激!!
您的查询对我来说还不错。 但是,您可以简化它:
SELECT description, suggested_by, voted, votes
FROM shop_suggestions s LEFT JOIN
(SELECT suggestion, COUNT(student) as votes,
MAX(student = 60910) as voted
FROM shop_suggestion_votes
GROUP BY suggestion
) votes
ON (votes.suggestion = s.id)
WHERE approved > 0 OR suggested_by = 60910
ORDER BY votes;
如果我不得不猜测实际的问题,我猜您可能简化了查询,并删除了令人讨厌的问题。 据记录,MySQL的一些常用(错误)功能不能总是起作用,但无论如何都可以使用它们。 我想到的是在select
中使用不在group by
。 另一个是使用变量的表达式的求值顺序。 您的代码都没有这些,但是也许您的原始代码有可疑之处。
您发现了一个错误,在该错误中,优化器在知道left join
是否有任何结果之前直接采用文字。 它是一个已知错误的派生, 错误#77707当涉及文字表达式时,右外部联接返回错误的结果 ( left join
联接-version已与此合并)。
它应该在5.7.8中修复,
在外部联接的内侧上的视图和派生表可能会产生错误的结果,并且从中选择了不可为空的表达式(如文字)。 (错误#73953,错误#20841369,错误#67014,错误#15967464,错误#65936,错误#14358878,错误#67300,错误#15936817,错误#76327,错误#20708288)
由于(新)文件排序具有其自己的优化器,因此似乎该错误仍然存在,并在使用order by
时重新出现(之前,无论是否进行排序)。
发送错误报告。
为了使您的查询正常工作,您可以(除Gordons重写的代码外)通过以下方式诱使mysql评估某些内容(从而无法优化文字):
...
LEFT JOIN (SELECT suggestion,
case when student = student then 1 else null end AS voted
FROM shop_suggestion_votes WHERE student = 60910) AS voted
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.