首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL -嵌套查询计数还快吗?

问SQL -嵌套查询计数还快吗?
EN

Stack Overflow用户
提问于 2018-11-13 17:49:07
回答 2查看 267关注 0票数 1

假设我有如下查询:

代码语言:javascript
复制
SELECT message.mid
FROM message
WHERE message.mid <= 100

据我所知,如果将查询更改为以下内容,它将执行得更快,因为列没有展开。

代码语言:javascript
复制
SELECT COUNT(message.mid)
FROM message
WHERE message.mid <= 100

但是,下面的查询会有同样的好处吗?还会一样快吗?

代码语言:javascript
复制
SELECT COUNT(*)
FROM (
    SELECT message.mid,
           message.something,
           message.something2,
           message.something3,
    FROM message
    WHERE message.mid <= 100
) AS A
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-14 20:22:45

COUNT(*)说要数行。

COUNT(x)说要计数x IS NOT NULL所在的行。所以稍微慢一点,可能会有不同的答案。

SELECT mid (相对于SELECT COUNT(...)) --更慢更笨重。它返回mid的所有值,而不仅仅是一个数字。

SELECT COUNT(..) FROM ( SELECT ... ) --速度要慢得多(在较早的MySQL版本中),因为它必须生成一个具有子查询结果的临时表。而且,COUNT只收集一个简单的数字;子查询收集了很多行。

如果mid被索引(这包括PRIMARY KEY,那么WHERE mid <= 100是索引(或表)的“范围”扫描)。也就是说,它只触及一些行。

如果没有索引mid,那么整个表将被扫描--因此速度更慢。

票数 1
EN

Stack Overflow用户

发布于 2018-11-13 18:20:09

我们可以问MySQL它会做什么。这是5.7。

代码语言:javascript
复制
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)

看起来是一样的。MySQL优化了子查询。

下面是一个示例,说明当MySQL不优化子查询时会看到什么。

代码语言:javascript
复制
mysql> explain SELECT * FROM (     SELECT message.mid     FROM message where mid < 100 group by mid) m;
+----+-------------+------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table      | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|  1 | PRIMARY     | <derived2> | NULL       | ALL   | NULL          | NULL    | NULL    | NULL |   99 |   100.00 | NULL                     |
|  2 | DERIVED     | message    | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL |   99 |   100.00 | Using where; Using index |
+----+-------------+------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+

“优化派生表和视图引用”有这种优化工作的例子。

示例1: 选择* FROM (SELECT * t1)作为derived_t1; 通过合并,该查询的执行方式类似于: 从t1中选择*;

该页面概述了MySQL为提高子查询效率而使用的许多其他优化技巧。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53286825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档