mariadb 如果HAVING子句运行得更快,那么将WHERE子句的一部分移到HAVING子句中是否有错?

yyhrrdl8  于 2022-11-08  发布在  其他
关注(0)|答案(2)|浏览(190)

在我的不使用聚合的长而复杂的查询中,我已经将AND ed where子句的一个部分移到了新的HAVING子句中。
从逻辑上讲,结果是一样的,行在返回之前被过滤。
从语义上讲,结果可能会在某些方面有所不同,我不明白。
但是从性能上来说,它的运行速度要快3倍。我知道这是因为我移动的东西是在做一个代价高昂的NOT EXISTS (SELECT ...)。以前,服务器花时间来评估可以使用其他更简单的规则排除的行。

使用此优化方法时,我是否违反了任何官方或非官方规则?

to94eoyn

to94eoyn1#

不,没有这样的规则。
由于连接在WHERE子句之前,因此可以减少将根据WHERE子句进行检查得行数.
它通常会受到一些奉承,因为您可能会错过一些需要的行。
所以基本上你可以这样做,但必须检查,如果所有需要的行都在那里。

oipij1gg

oipij1gg2#

  • WHERE子句的顺序ANDed在一起--〉优化器如果可以自由重新排列,但是
  • 但也有一些例外:首先搜索FULLTEXT;最后是子查询。(我不确定这一点。)
  • 引用聚合--〉必须在HAVING
  • 否则,WHEREHAVING具有相同的语义。
  • WHERE在逻辑上 * 在 * GROUP BY之前 * 完成; HAVING在之后完成。
  • 看起来您已经发现,如果NOT EXISTS在某种程度上被迫在其他测试之后进行,那么它会更有效;而将其移动到HAVING似乎已经实现了这一点。

提交一个错误报告(jira.mariadb.com),建议您发现一个优化器没有像它应该的那样处理好子句的情况。
如果你给我们看实际的查询,我们也许能深入挖掘。

相关问题