繁体   English   中英

Mysql IN()vs UNION ALL性能

[英]Mysql IN() vs UNION ALL performance

有人可以解释以下两个查询的性能特征的区别吗?

查询1

SELECT id FROM users WHERE status IN(1, 6, 11, 13);

查询2

(SELECT id FROM users WHERE status = 1)
UNION ALL
(SELECT id FROM users WHERE status = 6)
UNION ALL
(SELECT id FROM users WHERE status = 11)
UNION ALL
(SELECT id FROM users WHERE status = 13)

我知道查询#1对于人类来说要清晰得多。

我对有关它们的性能特征如何相同或不同的讨论感兴趣。 您可以假设在users.status上有一个索引

在第二个查询中,您要分别查询表。 对于每个select它必须读取一个表。 在第一种方法中,它必须读取一次表格。

使用索引,性能不会有太大不同。

如果没有索引,则每个表读取都必须是全表扫描,并且这两种方法之间的性能差异将更大。

因此,第一次查询将更快。

对于索引,从性能的角度来看,两者应基本相等。 索引可用时的基本过程是索引查找,以获取匹配的行,然后获取数据页。 第一个在单个查询单元中执行了四次。 第二个在一个ID上执行四个查询单元。

如果没有索引,则第一个应该更快-如果每次需要从磁盘读取表,则要快四倍。 如果表适合可用内存,并且随后的扫描使用热数据页缓存,则仅以递增的速度进行。

第一个会更快。 您可以通过分析来查看它:

mysql> SET profiling = 1;
mysql> select * from bigtable where id in (200, 900, 22000, 88888);
mysql> select * from bigtable where id =200
-> union all
-> select * from bigtable where id =900
-> union all
-> select * from bigtable where id =22000
-> union all
-> select * from bigtable where id =88888;
mysql> show profile for query 1;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000046 |
| checking permissions | 0.000006 |
| Opening tables       | 0.000013 |
| init                 | 0.000024 |
| System lock          | 0.000008 |
| optimizing           | 0.000009 |
| statistics           | 0.000031 |
| preparing            | 0.000010 |
| executing            | 0.000003 |
| Sending data         | 0.000072 |
| end                  | 0.000004 |
| query end            | 0.000006 |
| closing tables       | 0.000006 |
| freeing items        | 0.000013 |
| cleaning up          | 0.000008 |
+----------------------+----------+
15 rows in set, 1 warning (0,00 sec)

mysql> show profile for query 2;
+----------------------+----------+                                                                                                                                 
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000054 |
| checking permissions | 0.000006 |
| checking permissions | 0.000002 |
| checking permissions | 0.000003 |
| checking permissions | 0.000004 |
| Opening tables       | 0.000112 |
| init                 | 0.000058 |
| System lock          | 0.000009 |
| optimizing           | 0.000008 |
| statistics           | 0.000032 |
| preparing            | 0.000009 |
| optimizing           | 0.000005 |
| statistics           | 0.000017 |
| preparing            | 0.000005 |
| optimizing           | 0.000005 |
| statistics           | 0.000014 |
| preparing            | 0.000005 |
| optimizing           | 0.000005 |
| statistics           | 0.000014 |
| preparing            | 0.000006 |
| executing            | 0.000003 |
| Sending data         | 0.000018 |
| executing            | 0.000003 |
| Sending data         | 0.000008 |
| executing            | 0.000003 |
| Sending data         | 0.000007 |
| executing            | 0.000003 |
| Sending data         | 0.000007 |
| end                  | 0.000004 |
| query end            | 0.000007 |
| removing tmp table   | 0.000009 |
| query end            | 0.000002 |
| closing tables       | 0.000008 |
| freeing items        | 0.000020 |
| cleaning up          | 0.000011 |
+----------------------+----------+
35 rows in set, 1 warning (0,00 sec)

因此,即使在查询使用索引的情况下实际执行速度很快,联合内部各个查询的开销仍然存在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM