如何使用 MySQL 中的 Between 子句加快计数(不同)

How to speed up count(distinct) with Between clause in MySQL

我有一个 MySQL table 的 1000 万行和 3 列,格式如下:

id                                     time                               num

ca65e871-d758-437e-b76f-175234760e7b  2020-11-14 23:08:05.553770          11112222222
...

对于下面的第一个查询 运行,我在 (num, time) 上为 table 建立了索引,它运行得非常快(<5 毫秒处理 1000 万行 table):

SELECT COUNT(*) 
FROM TABLE_NAME 
WHERE time >= '2020-11-14 23:08:05.553752' AND num = 11112222222

但是我还需要在同一个 table 上执行 count(distinct)between 子句,像这样:

SELECT COUNT(DISTINCT num) 
FROM TABLE_NAME 
WHERE time >= '2020-11-14 23:08:05.553752'
  AND num BETWEEN (11112222222 - 30)
              AND (11112222222 + 30)

事实证明这要慢得多,大约 200 毫秒。 有没有办法加快第二个查询在同一个 table?

上的执行时间

如果你的 MySQl 是 8+,那么试试:

WITH RECURSIVE
cte AS ( SELECT 11112222222 - 30 num
         UNION ALL
         SELECT num + 1 FROM cte WHERE num < 11112222222 + 30 )
SELECT COUNT(*)
FROM cte
WHERE EXISTS ( SELECT NULL
               FROM TABLE_NAME 
               WHERE TABLE_NAME.num = cte.num
                 AND time >= '2020-11-14 23:08:05.553752' )

如果您经常执行此类查询,那么我建议使用从 -30 到 30 的数字创建服务 table,并使用它代替递归 CTE。

这是一个二维问题。而您的 WHERE 子句就像一个“边界框”。

添加 INDEX(time, num) 给优化器另一个选择。

如果您希望有基于 2 个范围的更复杂的查询,请参阅 http://mysql.rjweb.org/doc.php/find_nearest_in_mysql