MySQL 中的 UNION ALL 和 LIMIT

Posted

技术标签:

【中文标题】MySQL 中的 UNION ALL 和 LIMIT【英文标题】:UNION ALL and LIMIT in MySQL 【发布时间】:2010-10-24 13:45:25 【问题描述】:

假设我要执行这个查询:

(SELECT a FROM t1 WHERE a=10 AND B=1) 
UNION ALL 
(SELECT a FROM t2 WHERE a=11 AND B=2) 
UNION ALL 
(SELECT a FROM t3 WHERE a=12 AND B=3) 
ORDER BY a LIMIT 1000;

如果“t1”中有 550 个结果可用,“t2”中有 450 个结果可用,mysql 是否足够聪明,可以跳过“t3”?

我正在查看 MySQL 文档 (http://dev.mysql.com/doc/refman/5.1/en/union.html),但似乎找不到答案。

【问题讨论】:

【参考方案1】:

目前,即使前几个查询中有足够的行,MySQL 也会在联合上执行所有选择,正如@Yuki Inoue 在他们的回答中提到的那样。使用@user1477929 的答案,您可以将查询重写为:

(SELECT a FROM t1 WHERE a=10 AND B=1 LIMIT 1000) 
UNION ALL 
(SELECT a FROM t2 WHERE a=11 AND B=2 LIMIT 1000) 
UNION ALL 
(SELECT a FROM t3 WHERE a=12 AND B=3 LIMIT 1000) 
ORDER BY a LIMIT 1000;

这将给你最多 1000 行,并且永远不会扫描超过 3000 行。

【讨论】:

如果ORDER BY a LIMIT 500,1000 会发生什么? Mysql 从三个表中创建具有 3000 个结果(最大)的临时表,然后从临时表中获取第 501 行?还是别的什么?【参考方案2】:

它适用于我,我正在使用 MySQL。

但要确保所有人的限制数量始终相同

在该示例中,它会从每个表中为您提供 3 个结果

 (SELECT a FROM t1 WHERE a=10 AND B=1 LIMIT 9) 
 UNION ALL 
 (SELECT a FROM t2 WHERE a=11 AND B=2 LIMIT 9) 
 UNION ALL 
 (SELECT a FROM t3 WHERE a=12 AND B=3 LIMIT 9)

【讨论】:

【参考方案3】:

如果你有一个非常大的表,那么你可以执行下面的查询来看看 MySQL 优化器有多聪明......

(
  select * from very_large_table
  union all
  select * from very_large_table
) limit 1

遗憾的是,与以下查询相比,此查询需要很长时间。

select * from very_large_table limit 1

似乎每当需要UNION的结果时,MySQL都会首先计算UNION结果的整个临时表。

版本

MySQL 8.0.11

【讨论】:

【参考方案4】:

在 UNION 语法描述 (http://dev.mysql.com/doc/refman/5.1/en/union.html) 中指定:

UNION 的默认行为是 重复的行被从 结果。可选的 DISTINCT 关键字 除了默认值之外没有任何影响 因为它还指定 重复行删除。随着 可选 ALL 关键字,重复行 删除不会发生,结果 包括所有匹配的行 SELECT 语句。

我想,这就是你问题的答案。

【讨论】:

在结果集中,来自 t1 的数据是否总是在 t2 和 t3 之前,而 t2 在 t3 之前?我需要读取按“B ASC”排序的数据,并想知道是否可以跳过联合后的“按 B ASC 排序”。 在手册中指定,“UNION 默认会产生一组无序的行”,所以据我了解,不能保证。 @Kel 请告知如果第一次使用LIMIT 0,5 并在第二次查询时会发生什么,例如LIMIT 5,10?无序的行集,但我希望LIMIT 5,10 不会有LIMIT 0,5 的行?无序,但我希望所有查询的顺序相同? 正如我测试的sqlfiddle.com/#!9/09b72b/6 似乎UNION 总是创建具有相同结果顺序的临时表。并且使用不同的LIMIT 我将获得唯一(不重复)的结果。【参考方案5】:

是的,如果从t1t2 返回的结果等于LIMIT,MySql 足够聪明,可以跳过t3。事实上,这是默认行为。

【讨论】:

以上是关于MySQL 中的 UNION ALL 和 LIMIT的主要内容,如果未能解决你的问题,请参考以下文章

mysql中union和union all的区别和注意点

MySQL 中的 UNION ALL 和 LIMIT

mysql的union和union all

MYSQL union 和union all 用法 /

MYSQL union 和union all 用法 /

Mysql联合查询UNION和UNION ALL的使用介绍