繁体   English   中英

检查表中是否存在行的最有效方法是什么?

[英]What's the most efficient way to check the presence of a row in a table?

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

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

这两个查询之间有什么不同吗? 是否花费了返回每一列,或者是否花费了过滤掉我们不关心的列?

SELECT COUNT(*) FROM table WHERE id=5

这是一个全新的问题。 服务器是否会获取所有值然后计算值(比平时更难),或者它是否会费心抓取任何东西并且每次找到匹配时都会增加变量(比平常更容易)?

我想我对MySQL的工作方式做了很多错误的假设,但这就是问题的关键所在! 我哪里错了? 教育我,Stack Overflow!

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

SELECT COUNT(1) FROM mytable WHERE id = 5

最明确的方式是

选择WHIS EXISTS(SELECT 1 FROM table WHERE id = 5)THEN 1 ELSE 0 END

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

如果你SELECT COUNT(*)(或COUNT其他任何东西),它会在相同的情况下计算索引条目,但不会读取记录。

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

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

SELECT id FROM table WHERE id=5 LIMIT 1

这肯定会确保返回或处理的行不超过一行。 根据我的经验,检查行存在的LIMIT 1(或数据库中的TOP 1)在大表的性能方面有很大差异。

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

我会这么想的

SELECT null FROM table WHERE id = 5 LIMIT 1;

会比这更快

SELECT 1 FROM table WHERE id = 5 LIMIT 1;

但计时器说赢家是“SELECT 1”。

对于前两个查询,大多数人通常会说,总是准确指出您需要的内容并保留其余内容。 努力并非都是特定的,因为带宽可能用于返回您甚至不会做任何事情的数据。

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

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

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

暂无
暂无

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

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