Mysql 中是 limit 的优先级高还是 select count(*) 优先级高?

有这么一个查询 SQL:

select
    count(*)
from
    tweets
where
    user_id in (1, 2, 3)
    and status = 'online'
limit
    10

假设:

  • tweets 表有 10000000000000000 行数据
  • 符合 user_id in (1, 2, 3)status = 'online' 两个条件的有 10000 行
  • 建立了联合索引 uk_index(user_id,status)
  • 确定走了联合索引 uk_index
  • 我只要 limit 10

上面的 SQL

  • 情况一:一共只会扫描 10 行,然后返回一个 10
  • 情况二:还是会扫描 10000 行,然后返回一个 10?

我觉得应该是情况一,但是好像从访问速度来看,是情况二?


为什么我有这个疑问,就是我一般是这么用的

select
    *
from
    tweets
where
    user_id in (1, 2, 3)
    and status = 'online'
limit
    10

一般 10 秒可以出结果

但是闲来无事,改成:

select
    count(*)
from
    tweets
where
    user_id in (1, 2, 3)
    and status = 'online'
limit
    10

结果过了半小时都没有出结果

所以就有了这个疑问


下面说说为什么有这个需求:

为什么有和这个需求,很简单,比如一个分页,我需要告诉 user ,一共有几页,或者说 total

但是下面 SQL 的成本是无法承受之重的:

select
    count(*)
from
    tweets
where
    user_id in (1, 2, 3)
    and status = 'online';

所以,我就采用上限模糊法, 就是如果 total 超过200 就只显示 200+

所以这个时候,统计 total 的 SQL 就变成了:

select
    id
from
    tweets
where
    user_id in (1, 2, 3)
    and status = 'online'
limit
    201

客户端判断一个 len(rows) 是不是 201,是 201 就说明是 200+,小于 201 就显示具体值

但是 select id 要返回 201 个 id,就是 201x4=804 个字节,我觉得没有必要,浪费网络 IO,所以,最好可以:

select
    count(id)
from
    tweets
where
    user_id in (1, 2, 3)
    and status = 'online'
limit
    201

这样客户端可以直接判断 assert count==201 是不是等于 201,从 804 字节变成了 4 字节

阅读 2.4k
1 个回答

从你的需求来看,直接用个子查询好了:

select count(*) 
from (
  select
      id
  from
      tweets
  where
      user_id in (1, 2, 3)
      and status = 'online'
  limit
      201
) tmp;

希望能帮助到你。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题