简体   繁体   English

检查MySQL表是否为空:COUNT(*)为零而LIMIT(0,1)是否为结果?

[英]Check if MySQL Table is empty: COUNT(*) is zero vs. LIMIT(0,1) has a result?

This is a simple question about efficiency specifically related to the MySQL implementation. 这是一个关于效率的简单问题,与MySQL实现有关。 I want to just check if a table is empty (and if it is empty, populate it with the default data). 我想检查一个表是否为空(如果它是空的,则使用默认数据填充它)。 Would it be best to use a statement like SELECT COUNT(*) FROM `table` and then compare to 0, or would it be better to do a statement like SELECT `id` FROM `table` LIMIT 0,1 then check if any results were returned (the result set has next)? 是否最好使用SELECT COUNT(*) FROM `table` ,然后比较为0,或者更好的做一个语句,如SELECT `id` FROM `table` LIMIT 0,1然后检查是否有返回结果(结果集有下一个)?

Although I need this for a project I am working on, I am also interested in how MySQL works with those two statements and whether the reason people seem to suggest using COUNT(*) is because the result is cached or whether it actually goes through every row and adds to a count as it would intuitively seem to me. 虽然我需要这个用于我正在开发的项目,但我也对MySQL如何处理这两个语句感兴趣,以及人们似乎建议使用COUNT(*)的原因是因为结果是缓存还是它实际上是通过每个排,并添加到计数,因为它在我看来是直观的。

You should definitely go with the second query rather than the first. 你绝对应该使用第二个查询而不是第一个查询。

When using COUNT(*) , MySQL is scanning at least an index and counting the records. 当使用COUNT(*) ,MySQL正在扫描至少一个索引并计算记录。 Even if you would wrap the call in a LEAST() ( SELECT LEAST(COUNT(*), 1) FROM table; ) or an IF() , MySQL will fully evaluate COUNT() before evaluating further. 即使你将调用包装在LEAST()SELECT LEAST(COUNT(*), 1) FROM table; )或IF() ,MySQL也会在进一步评估之前完全评估COUNT() I don't believe MySQL caches the COUNT(*) result when InnoDB is being used. 我不相信MySQL在使用InnoDB时会缓存COUNT(*)结果。

Your second query results in only one row being read, furthermore an index is used (assuming id is part of one). 您的第二个查询导致只读取一行,此外还使用索引(假设id是一个的一部分)。 Look at the documentation of your driver to find out how to check whether any rows have been returned. 查看驱动程序的文档,了解如何检查是否已返回任何行。 By the way, the id field may be omitted from the query (MySQL will use an arbitrary index): 顺便说一句,可以从查询中省略id字段(MySQL将使用任意索引):

SELECT 1 FROM table LIMIT 1;

However, I think the simplest and most performant solution is the following (as indicated in Gordon's answer): 但是,我认为最简单,最高效的解决方案如下(如Gordon的回答所示):

SELECT EXISTS (SELECT 1 FROM table);

EXISTS returns 1 if the subquery returns any rows, otherwise 0 . 如果子查询返回任何行,则EXISTS返回1 ,否则返回0 Because of this semantic MySQL can optimize the execution properly. 由于这种语义,MySQL可以正确地优化执行。 Any fields listed in the subquery are ignored, thus 1 or * is commonly written. 子查询中列出的任何字段都将被忽略,因此通常会写入1*

See the MySQL Manual for more info on the EXISTS keyword and its use. 有关EXISTS关键字及其用法的更多信息,请参阅MySQL手册

It is better to do the second method or just exists . 最好是做第二种方法或只是exists Specifically, something like: 具体来说,类似于:

if exists (select id from table)

should be the fastest way to do what you want. 应该是做你想做的最快的方式。 You don't need the limit ; 你不需要limit ; the SQL engine takes care of that for you. SQL引擎为您处理这个问题。

By the way, never put identifiers (table and column names) in single quotes. 顺便说一下,永远不要将标识符(表名和列名)放在单引号中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM