检查表中是不是存在行的最有效方法是啥?

Posted

技术标签:

【中文标题】检查表中是不是存在行的最有效方法是啥?【英文标题】:What's the most efficient way to check the presence of a row in a table?检查表中是否存在行的最有效方法是什么? 【发布时间】:2009-01-28 02:27:26 【问题描述】:

假设我想检查 mysql 表中的记录是否存在。我会运行一个查询,检查返回的行数。如果有 0 行,则执行此操作,否则执行此操作。

SELECT * FROM table WHERE id=5
SELECT id FROM table WHERE id=5

这两个查询之间有什么区别吗?是花精力返回每一列,还是花精力过滤掉我们不关心的列?

SELECT COUNT(*) FROM table WHERE id=5

是一个全新的问题。服务器会抓取所有值然后计算这些值(比平常更难),还是它不会费心抓取任何东西而只是在每次找到匹配项时增加一个变量(比平常更容易)?

我认为我对 MySQL 的工作原理做出了很多错误的假设,但这就是问题的实质!我哪里错了?教育我,堆栈溢出!

【问题讨论】:

AFAIK,这将取决于您的 MySQL 数据库使用的实际存储类型,例如InnoDB 与 MyISAM。您使用哪个数据库? 这是一个比较笼统的问题,所以我想说“这取决于存储类型”本身就是答案! 可以使用这里描述的方法之一***.com/q/9026184/1168944 【参考方案1】:

优化器非常聪明(通常)。他们通常只抓住他们需要的东西,所以我会选择:

SELECT COUNT(1) FROM mytable WHERE id = 5

【讨论】:

【参考方案2】:

最明确的方式是

SELECT WHEN EXISTS (SELECT 1 FROM table WHERE id = 5) THEN 1 ELSE 0 END

如果在 id 上(或以 id 开头)有索引,它只会以最高效率搜索索引中它可以找到具有该值的第一个条目。它不会读取记录。

如果您选择 COUNT(*)(或 COUNT 其他任何内容),在相同情况下,它将计算索引条目,但不读取记录。

如果您选择 *,它将读取所有记录。

【讨论】:

【参考方案3】:

如果您只想检查记录的存在,请通过附加 LIMIT 1 将结果限制为最多一行。

SELECT id FROM table WHERE id=5 LIMIT 1

这肯定会确保返回或处理的行不超过一行。根据我的经验,检查行是否存在的 LIMIT 1(或 TOP 1,取决于数据库)对大型表的性能有很大影响。

编辑:我想我误读了你的问题,但如果有任何帮助,我还是会把答案留在这里。

【讨论】:

【参考方案4】:

我会这么认为

SELECT null FROM table WHERE id = 5 LIMIT 1;

会比这更快

SELECT 1 FROM table WHERE id = 5 LIMIT 1;

但计时器显示获胜者是“SELECT 1”。

【讨论】:

【参考方案5】:

对于前两个查询,大多数人通常会说,始终准确地指定您需要的内容,其余的则保留。努力并非都是具体的,因为带宽可能会花费在返回您甚至不会做任何事情的数据上。

至于前面的答案将适用于您的结果集,除非您正在处理支持受影响行的语言。这有时可以在获取数据以收集有关上次查询中返回的行数的信息时起作用。您需要查看接口文档以了解如何获取该信息。

【讨论】:

【参考方案6】:

您的 3 个查询之间的差异取决于您构建索引的方式。仅返回主键可能会更快,因为 MySQL 会将您的索引保存在内存中,而不必访问磁盘。添加LIMIT 1 也是一个很好的技巧,它将在早期的 5.0.x 分支和更早版本中显着加快优化器的速度。

尝试EXPLAIN SELECT id FROM table WHERE id=5 并检查附加列是否存在USING INDEX。如果它在那里,那么您的查询直接来自索引,并且会更快。

【讨论】:

以上是关于检查表中是不是存在行的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

检查 SQL Server 中是不是存在触发器的最便携方法是啥?

检查 JavaScript 中是不是存在深度嵌套对象属性的最简单方法是啥? [复制]

检查未知对象中的对象是不是存在的最有效的Javascript方法[重复]

在 SQL Server 中检查逗号分隔字符串中是不是存在子字符串的最有效方法

检查 DBNull 然后分配给变量的最有效方法是啥?

如果路径已知,检查 Firestore 记录是不是存在的最佳方法是啥?