12

当我优化我的 2 个单个查询以在 0.02 秒内运行,然后UNION它们生成的查询需要超过 1 秒才能运行。此外, aUNION ALL比 a 花费更长的时间UNION DISTINCT

我假设允许重复会使查询运行得更快而不是更慢。我真的最好分开运行这两个查询吗?我更喜欢使用UNION.

作为一个简单的例子,如果我这样做

SELECT name FROM t1 WHERE field1 = true

需要 0.001 秒

如果我这样做

SELECT name FROM t1 WHERE field1 = false

它需要 0.1 秒。

如果我再跑

SELECT name FROM t1 WHERE field1 = true 
UNION ALL 
SELECT name FROM t1 WHERE field1 = false

它需要超过 1 秒。

4

5 回答 5

17

当我优化我的 2 个单个查询以在不到 0.02 秒的时间内运行,然后将它们联合起来,生成的查询需要超过 1 秒的时间才能运行。

您的查询是否包含ORDER BY … LIMIT子句?

如果你ORDER BY … LIMIT在 a 之后放一个UNION,它会被应用到整个UNION,并且在这种情况下不能使用索引。

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

SELECT  *
FROM    table
ORDER BY id
LIMIT 1

,但这个不会:

SELECT  *
FROM    table
UNION ALL
SELECT  *
FROM    table
ORDER BY id
LIMIT 1

此外, aUNION ALL比 a 花费更长的时间UNION DISTINCT。我假设允许重复会使查询运行得更快而不是更慢。

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

我真的最好分开运行这两个查询吗?我宁愿使用UNION

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

如果没有,只需摆脱 final ORDER BY

于 2009-05-16T00:36:09.450 回答
4

一个猜测:由于您使用 2 个联合查询一个表,因此 mysql 可能难以确定该表的锁定策略,或者它尝试一些缓存,这在这里不起作用,因为您查询不相交的集合,尝试多线程访问(非常合理)但遇到一些锁定/并发/文件搜索问题..

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

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

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

知道您使用哪种存储引擎会很有用。

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

于 2009-05-15T18:48:18.460 回答
4

关于UNION

  • UNION DISTINCT(的默认值UNION)必然较慢,因为它必须收集两个结果,然后进行重复数据删除。但是,由于退回给客户的数量较少,因此可能会有一些补偿。
  • 直到最近的版本, UNIONs涉及一个临时表来收集结果,因此UNION必然比两个单独SELECTs的 . 最近,(MySQL 5.7、MariaDB 10.1)一些案例UNION ALL得到了改进,可以将数据从一个SELECT直接传递到客户端,然后再传递其他的。
  • SELECT .. UNION SELECT .. ORDER BY ..相当于--this --not this
    (SELECT .. UNION SELECT ..) ORDER BY .. 建议 总是在每个.
    (SELECT ..) UNION (SELECT .. ORDER BY ..)
    SELECT
  • 排序(通过ORDER BY可能需要额外的时间来处理它所附加的任何(选择或联合)。不太可能花费更少的时间。简单地说,优化器的目标是做任何最快的事情,这可能恰好是排序的。
  • 所有这些陈述都适用于 InnoDB;MyISAM 不太受支持,可能缺少一些最近的优化。
  • SELECT有时,带有a 的单个OR可以通过将其转换为 a 来加速UNION,从而使用两个索引。

关于测试:

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

UNION ALL 比 UNION 快,因为普通的 UNION 期望在两个连接的数据集中存在需要删除的重复项。如果您可以(通过内部 WHERE 子句)确保没有重复项,则最好使用 UNION ALL 并让数据库引擎优化内部选择。

对分组结果的结果使用 WHERE 子句过于昂贵,因为您操作的内部结果超出了您的需要。此外,无法处理数据库引擎的优化——结果没有任何共同点。

检查此链接以获取详细信息https://dzone.com/articles/performance-tip-for-tuning-sql-with-union

于 2019-12-02T11:08:15.190 回答
-1

可能是您测量响应时间而不是检索所有数据的时间吗?

于 2009-09-16T10:08:29.797 回答