Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL-嵌套查询的计数是否仍然很快?_Mysql_Sql_Performance_Database Performance - Fatal编程技术网

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;