为什么UNION查询在MySQL中这么慢?

Gre*_*reg 10 mysql union query-optimization

当我优化我的2个单个查询以在不到0.02秒内运行然后UNION它们时,生成的查询需要超过1秒才能运行.此外,UNION ALL比UNION DISTINCT需要更长的时间.我认为允许重复会使查询运行得更快,而不是更慢.我真的最好分开运行2个查询吗?我更愿意使用UNION.

Qua*_*noi 15

当我优化我的2个单个查询以在不到0.02秒内运行然后UNION它们时,生成的查询需要超过1秒才能运行.

您的查询是否包含ORDER BY … LIMIT条款?

如果你把一个ORDER BY … LIMIT后面的UNION,它应用到整体UNION,并且在这种情况下不能使用索引.

如果id是主键,则此查询将是即时的:

SELECT  *
FROM    table
ORDER BY id
LIMIT 1
Run Code Online (Sandbox Code Playgroud)

,但这个不会:

SELECT  *
FROM    table
UNION ALL
SELECT  *
FROM    table
ORDER BY id
LIMIT 1
Run Code Online (Sandbox Code Playgroud)

而且,UNION ALL花费的时间比a长UNION DISTINCT.我认为允许重复会使查询运行得更快,而不是更慢.

这也似乎是由于ORDER BY.对较小的集进行排序比对较大的集更快.

我真的最好分开运行2个查询吗?我更愿意使用UNION

您是否需要对结果集进行排序?

如果没有,只需摆脱决赛ORDER BY.


And*_*asT 5

猜测:既然你查询一个有2个联合的表,那么mysql可能很难决定表的锁定策略,或者它尝试一些缓存,这在这里不起作用,因为你查询不相交的集合,尝试多线程访问(非常合理),但遇到一些锁定/并发/文件查找问题。

工会通常也可能采用更高的安全设置,因为这两个选择必须一致。如果您将它们放入单独的交易中,它们就不会。

实验:复制该表并将它们合并。如果我是对的,应该会更快。

可能的解决方案:将单个文件拆分为多个文件,以实现更好的并发策略。这不会/不应该帮助解决锁定问题,但排除数据库中的多线程/查找问题。

了解您使用哪种存储引擎会很有用。

好吧,只是我的 2 美分。现在无法在这里进行测试。


Ric*_*mes 5

关于UNION

  • UNION DISTINCT(默认值UNION)必然较慢,因为它必须收集两个结果,然后进行重复数据删除。然而,由于返还给客户的金额较少,因此可能会有一些补偿。
  • 直到最近的版本,所有 UNIONs版本都涉及一个临时表来收集结果,因此UNION必然比两个单独的SELECTs. 最近,(MySQL 5.7、MariaDB 10.1)某些情况下UNION ALL进行了改进,将数据从一个SELECT直接传送到客户端,然后再传送其他的。
  • SELECT .. UNION SELECT .. ORDER BY ..相当于
    (SELECT .. UNION SELECT ..) ORDER BY .. - this
    (SELECT ..) UNION (SELECT .. ORDER BY ..)- not this
    建议始终在每个周围使用括号SELECT
  • 对于附加的任何内容(选择或联合),排序(通过ORDER BY可能会花费额外的时间。花费更少的时间是不太可能的。简而言之,优化器的目标是尽可能快地完成可能排序的事情。
  • 所有这些说法都适用于InnoDB;MyISAM 支持不多,可能缺少一些最近的优化。
  • SELECT有时,可以通过将带有 an 的单个字符OR转换为 a 来加快速度UNION,从而使用两个索引。

关于测试:

  • 0.001 的时间听起来就像您之前运行过查询并且结果缓存在“查询缓存”中。通过关闭 QC 或添加SQL_NO_CACHE.
  • 选择WHERE flag = true (or false)有几种情况: 是否flag建立索引?几乎总是flag这些值之一?在这种情况下,将使用索引,并且可能比其他情况更快。
  • 如果您不同意我的任何陈述,请提供相反的工作示例。