MySQL高效测试,如果计数w / where大于一个值

时间:2017-04-04 22:54:58

标签: mysql count query-optimization where short-circuiting

有没有办法优化以下查询?

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

使用此查询,MySQL首先执行count(*)然后进行比较。当只有少数几行满足条件时,这是快速的,但如果很多行满足它,则可以永久保存。有没有办法在找到1000个项目后立即停止计数,而不是通过所有结果?

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

2 个答案:

答案 0 :(得分:4)

SELECT 1
    FROM table_with_lot_of_rows
    WHERE condition_on_index
    LIMIT 1000, 1;

以这种方式工作:

  1. 使用索引(可能比使用数据更快)
  2. 跳过1000行,收集 no 。 (这比其他答案要好。)
  3. 如果你做到这一点,请获取1行,仅包含文字1(在SELECT中)。
  4. 现在您要么为空结果集(< = 1000行),要么为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。注意:需要额外的parens。

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

答案 1 :(得分:1)

您可以使用LIMIT:

的子查询来优化查询
SELECT count(*)>1000 FROM (
    SELECT 0 table_with_lot_of_rows
    WHERE condition_on_index
    LIMIT 1001
) as truncated_count;

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