首页 文章

测试MySQL表中是否存在行的最佳方法

提问于
浏览
279

我试图找出表中是否存在行 . 使用MySQL,最好是这样做一个查询:

SELECT COUNT(*) AS total FROM table1 WHERE ...

并检查总数是否为非零或是否更好地执行这样的查询:

SELECT * FROM table1 WHERE ... LIMIT 1

并检查是否有任何行返回?

在两个查询中,WHERE子句都使用索引 .

12 回答

  • 2

    COUNT(*) 在MySQL中进行了优化,因此一般来说,前一个查询可能更快 .

  • -1

    我最近对这个问题做了一些研究 . 如果字段是TEXT字段,非唯一字段,则实现它的方式必须不同 .

    我用TEXT字段做了一些测试 . 考虑到我们有一个包含1M条目的表的事实 . 37个条目等于'某事':

    • SELECT * FROM test WHERE texte LIKE '%something%' LIMIT 1mysql_num_rows() :0.039061069488525s . (FASTER)

    • SELECT count(*) as count FROM test WHERE text LIKE '%something% :16.028197050095s .

    • SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%') :0.87045907974243s .

    • SELECT EXISTS(SELECT 1 FROM test WHERE text LIKE '%something%' LIMIT 1) :0.044898986816406s .

    但现在,使用BIGINT PK字段,只有一个条目等于'321321':

    • SELECT * FROM test2 WHERE id ='321321' LIMIT 1 with mysql_num_rows() :0.0089840888977051s .

    • SELECT count(*) as count FROM test2 WHERE id ='321321' :0.00033879280090332s .

    • SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321') :0.00023889541625977s .

    • SELECT EXISTS(SELECT 1 FROM test2 WHERE id ='321321' LIMIT 1) :0.00020313262939453s . (FASTER)

  • 149

    我跟 COUNT(1) 一起去 . 它比 COUNT(*) 更快,因为 COUNT(*) 测试以查看该行中是否至少有一列是!= NULL . 您不需要这样,特别是因为您已经有条件( WHERE 子句) . COUNT(1) 而不是测试 1 的有效性,它始终有效并且测试时间要少得多 .

  • 0

    或者您可以将原始sql部分插入条件,所以我有'conditions' =>数组('Member.id NOT IN (SELECT Membership.member_id FROM memberships AS Membership)')

  • 0

    你也可以尝试使用

    SELECT EXISTS(SELECT * FROM table1 WHERE ...)
    

    the documentation

    Per a comment below:

    SELECT EXISTS(SELECT 1 FROM table1 WHERE ...)
    
  • 4

    我觉得值得指出的是,尽管评论中提到了这一点,但在这种情况下:

    SELECT 1 FROM my_table WHERE *indexed_condition* LIMIT 1
    

    优于:

    SELECT * FROM my_table WHERE *indexed_condition* LIMIT 1
    

    这是因为索引可以满足第一个查询,而第二个查询需要查找行(除非可能所有表的列都在使用的索引中) .

    添加 LIMIT 子句允许引擎在找到任何行后停止 .

    第一个查询应该与:

    SELECT EXISTS(SELECT * FROM my_table WHERE *indexed_condition*)
    

    它向发动机发送相同的信号,但我仍然写1以消除任何疑问:

    SELECT EXISTS(SELECT 1 FROM my_table WHERE *indexed_condition*)
    

    如果在没有行匹配时需要显式返回,则添加 EXISTS 包装可能是有意义的 .

  • 6

    在我的研究中,我可以发现结果跟随速度 .

    select * from table where condition=value
    (1 total, Query took 0.0052 sec)
    
    select exists(select * from table where condition=value)
    (1 total, Query took 0.0008 sec)
    
    select count(*) from table where condition=value limit 1) 
    (1 total, Query took 0.0007 sec)
    
    select exists(select * from table where condition=value limit 1)
    (1 total, Query took 0.0006 sec)
    
  • 2

    COUNT 查询速度更快,但可能并不明显,但只要获得所需结果,两者都应该足够了 .

  • -1

    @ ChrisThompson答案的简短例子

    Example:

    mysql> SELECT * FROM table_1;
    +----+--------+
    | id | col1   |
    +----+--------+
    |  1 | foo    |
    |  2 | bar    |
    |  3 | foobar |
    +----+--------+
    3 rows in set (0.00 sec)
    
    mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1);
    +--------------------------------------------+
    | EXISTS(SELECT 1 FROM table_1 WHERE id = 1) |
    +--------------------------------------------+
    |                                          1 |
    +--------------------------------------------+
    1 row in set (0.00 sec)
    
    mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 9);
    +--------------------------------------------+
    | EXISTS(SELECT 1 FROM table_1 WHERE id = 9) |
    +--------------------------------------------+
    |                                          0 |
    +--------------------------------------------+
    1 row in set (0.00 sec)
    

    使用别名:

    mysql> SELECT EXISTS(SELECT 1 FROM table_1 WHERE id = 1) AS mycheck;
    +---------+
    | mycheck |
    +---------+
    |       1 |
    +---------+
    1 row in set (0.00 sec)
    
  • -2

    建议你不要使用 Count 因为count总是为db使用 SELECT 1 做额外的加载,如果你的记录在那里它会返回 1 否则它返回null并且你可以处理它 .

  • 20

    有时,如果存在行的自动增量主键( id ),则非常方便,如果不存在,则为 0 .

    以下是在单个查询中如何完成此操作:

    SELECT IFNULL(`id`, COUNT(*)) FROM WHERE ...
    
  • 402

    对于非InnoDB表,您还可以使用信息模式表:

    http://dev.mysql.com/doc/refman/5.1/en/tables-table.html

相关问题