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

时间:2009-01-28 02:27:27

标签: sql mysql performance

说我想检查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!

6 个答案:

答案 0 :(得分:8)

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

SELECT COUNT(1) FROM mytable WHERE id = 5

答案 1 :(得分:4)

最明确的方式是

EXISTS时选择(SELECT 1 FROM表WHERE id = 5)那么1 ELSE 0 END

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

如果您选择COUNT(*)(或另外COUNT),它将在相同的情况下计算索引条目,但不会读取记录。

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

答案 2 :(得分:3)

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

SELECT id FROM table WHERE id=5 LIMIT 1

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

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

答案 3 :(得分:2)

我想这个

SELECT null FROM table WHERE id = 5 LIMIT 1;

会比这个更快

SELECT 1 FROM table WHERE id = 5 LIMIT 1;

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

答案 4 :(得分:0)

对于前两个查询,大多数人一般会说,总是准确指出你需要的东西,剩下的就剩下了。努力并非都是特定的,因为带宽可用于返回您甚至不会做任何事情的数据。

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

答案 5 :(得分:0)

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

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