Mysql SQL-嵌套查询的计数是否仍然很快?
假设我有一个如下的问题:Mysql SQL-嵌套查询的计数是否仍然很快?,mysql,sql,performance,database-performance,Mysql,Sql,Performance,Database Performance,假设我有一个如下的问题: SELECT message.mid FROM message WHERE message.mid <= 100 据我所知,如果将查询更改为以下内容,它将执行得更快,因为列没有展开 SELECT COUNT(message.mid) FROM message WHERE message.mid <= 100 但是下面的查询也有同样的好处吗?它还会这么快吗 SELECT COUNT(*) FROM ( SELECT message.mid,
SELECT message.mid
FROM message
WHERE message.mid <= 100
据我所知,如果将查询更改为以下内容,它将执行得更快,因为列没有展开
SELECT COUNT(message.mid)
FROM message
WHERE message.mid <= 100
但是下面的查询也有同样的好处吗?它还会这么快吗
SELECT COUNT(*)
FROM (
SELECT message.mid,
message.something,
message.something2,
message.something3,
FROM message
WHERE message.mid <= 100
) AS A
。这是5.7
mysql> explain SELECT COUNT(*) FROM ( SELECT message.mid FROM message WHERE message.mid <= 100
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | message | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 100 | 100.00 | Using where; Using index |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> explain SELECT count(message.mid) FROM message WHERE message.mid <= 100;
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| 1 | SIMPLE | message | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 100 | 100.00 | Using where; Using index |
+----+-------------+---------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)
通过合并,该查询的执行类似于:
SELECT * FROM t1;
该页面概述了MySQL用于提高子查询效率的许多其他优化技巧。COUNT*表示要计算行数
COUNTx表示对x不为NULL的行进行计数。所以稍微慢一点,可能是一个不同的答案
选择中期与选择计数…-更慢更笨重。它返回mid的所有值,而不仅仅是一个数字
选择计数。。从选择…-在较旧的MySQL版本中要慢得多,因为它必须生成一个包含子查询结果的临时表。此外,COUNT只是收集一个简单的数字;子查询正在收集大量行
如果mid是包含主键的索引,那么在何处mid如果不需要子查询,为什么要使用子查询?如果有索引messagemid,我假设正常的非子查询版本更快,因为查询将在覆盖索引上运行。对于5.7之前的MySQL版本,使用第三个查询,内联视图将使派生表具体化为中间临时表。完成后,外部查询将针对该临时表运行。在MySQL 5.7和8.0中,优化器得到了改进,因此内联视图查询可以合并到外部块中。如果用例只需要行数,那么使用带有count aggregate的查询。如果用例需要详细信息行,请使用只返回所需列的查询。@RaymondNijland问题没有解释它,但是我有一种情况,我需要使用一个子查询。@spencer7593我不知道5.7和8.0中的优化谢谢:那帮助我不知道5.7和8.0中的优化你可以在这里阅读文档是的,这是我需要的答案。非常感谢。速度要慢得多,因为它必须生成一个临时表。对于这样的简单情况,这是不正确的。MySQL可以将子查询合并到外部块中,使select count*从select。。。相当于选择计数*。。。。不需要临时表。见@Schwern-True;在最新版本中,优化器可以对某些查询执行此操作。我修改了我的陈述。
SELECT * FROM (SELECT * FROM t1) AS derived_t1;
SELECT * FROM t1;