MySQL 有效测试 count w/ where 是不是大于一个值

Posted

技术标签:

【中文标题】MySQL 有效测试 count w/ where 是不是大于一个值【英文标题】:MySQL efficient test if count w/ where is greater than a valueMySQL 有效测试 count w/ where 是否大于一个值 【发布时间】:2017-04-04 22:54:58 【问题描述】:

有没有办法优化下面的查询?

SELECT count(*)>1000 FROM table_with_lot_of_rows WHERE condition_on_index;

使用这个查询,mysql 首先执行count(*),然后进行比较。当只有少数行满足条件时,这很快,但如果很多行满足条件,则可能需要很长时间。有没有办法在找到 1000 个项目后立即停止计数,而不是遍历所有结果?

特别是,我对具有全文条件的 MyISAM 表感兴趣,但对 InnoDB 和/或基本 WHERE 子句的任何回答都会有所帮助。

【问题讨论】:

【参考方案1】:
SELECT 1
    FROM table_with_lot_of_rows
    WHERE condition_on_index
    LIMIT 1000, 1;

这样工作:

    使用索引(估计比使用数据快) 跳过 1000 多行,收集任何内容。 (这比其他答案更好。) 如果到此为止,请获取 1 行,其中仅包含文字 1(在 SELECT 中)。

现在您要么有一个空结果集(1(至少 1001 行)。

然后,根据您的应用程序语言,很容易区分这两种情况。

另一个注意事项:如果这是一个更大查询中的子查询,那么做

EXISTS ( SELECT 1
    FROM table_with_lot_of_rows
    WHERE condition_on_index
    LIMIT 1000, 1 )

返回 TRUE/FALSE(与 1 或 0 同义)。

面对现实,扫描 1001 行,甚至是索引,都需要 一些 时间。我认为我的配方是最快的。

要检查的其他事项:这是 InnoDB 吗? EXPLAIN 是否说“使用索引”?多少内存? innodb_buffer_pool_size的设置是什么?

请注意,InnoDB 现在有 FULLTEXT,因此没有理由坚持使用 MyISAM。

如果您使用的是 MyISAM 并且 WHEREMATCH...,那么我所说的大部分内容可能不适用。 FULLTEXT 可能在让引擎的其余部分有机会使用 ORDER BYLIMIT 进行这些游戏之前获取所有结果。

请向我们展示实际查询,即EXPLAINSHOW CREATE TABLE。真正的目标是什么?看看一个查询是否会提供“太多”的结果?

可能的改进(取决于上下文)

由于我的初始SELECT 返回标量1NULL,它可以用于任何布尔上下文,例如WHERE1TRUENULL 将被视为FALSE。因此EXISTS 可能是多余的。

另外,1/NULL 可以这样转换成1/0。注意:额外的括号是必需的。

IFNULL( ( SELECT ... LIMIT 1000,1 ), 0)

【讨论】:

很好的解决方案,谢谢!提供我的具体设置的详细信息可能与这个问题无关,这是为了改进基本的count(*)>1000,与索引无关。 FULLTEXTSPATIALPRIMARY 和其他索引有 4 种不同的工作方式。 在我提供赏金之后,我想出了一个修改版本,得到我想要的“0 or 1”而不是“nothing or 1”作为结果,没有重复阈值(违反 DRY),但它仍然是基于子查询的(感觉很难看)。我会留下赏金,看看是否有人可以在没有样式点子查询的情况下做到这一点,但除此之外,赏金是你激励我的。我的修改版本只是将它包装到COUNT 你的查询结果:SELECT COUNT(*) FROM (SELECT 1 FROM table_with_lot_of_rows WHERE condition_on_index LIMIT 1000, 1);【参考方案2】:

您可以使用带有 LIMIT 的子查询来优化查询:

SELECT count(*)>1000 FROM (
    SELECT 0 table_with_lot_of_rows
    WHERE condition_on_index
    LIMIT 1001
) as truncated_count;

在这种情况下,只要有足够的行满足条件,MySQL 就会停止。

【讨论】:

以上是关于MySQL 有效测试 count w/ where 是不是大于一个值的主要内容,如果未能解决你的问题,请参考以下文章

mysql 带条件的sum/count 使用技巧

MySQL - 在 WHERE 子句中使用 COUNT(*)

MySQL COUNT性能分析

开发经验mysql有效防止删库跑路!

mysql语句的简化:from中的临时表作为where中的条件

mysql count(*)和count(列)速率