查询索引/唯一字段时是否有任何使用MySQL“LIMIT 1”的点?

时间:2010-10-03 03:04:47

标签: sql mysql performance limit indexing

例如,我正在查询我知道将是唯一的字段并且已编入索引,例如主键。因此我知道这个查询只返回1行(即使没有LIMIT 1)

SELECT * FROM tablename WHERE tablename.id=123 LIMIT 1

或仅更新1行

UPDATE tablename SET somefield='somevalue' WHERE tablename.id=123 LIMIT 1

如果字段已编入索引,是否会添加LIMIT 1会改善查询执行时间?

5 个答案:

答案 0 :(得分:39)

查询主键/唯一字段时是否有使用MySQL“LIMIT 1”的任何意义?

在使用针对主键或唯一约束的过滤条件查询时,使用LIMIT 1不是一个好习惯。主键或唯一约束意味着表中只有一个行/记录具有该值,只返回一行/记录。在主键/唯一字段上使用LIMIT 1是矛盾的 - 稍后维护代码的人可能会误认为重要性和优先级。再猜你的代码。

但最终的指标是解释计划:

explain SELECT t.name FROM USERS t WHERE t.userid = 4

...返回:

id  | select_type | table   | type  | possible_keys  | key      | key_len  |  ref  |  rows  |  Extra
-----------------------------------------------------------------------------------------------------
1   | SIMPLE      | users   | const | PRIMARY        | PRIMARY  | 4        | const | 1      |

...和

explain SELECT t.name FROM USERS t WHERE t.userid = 4 LIMIT 1

...返回:

id  | select_type | table   | type  | possible_keys  | key      | key_len  |  ref  |  rows  |  Extra
-----------------------------------------------------------------------------------------------------
1   | SIMPLE      | users   | const | PRIMARY        | PRIMARY  | 4        | const | 1      |

结论

没有区别,没有必要。在这种情况下,它似乎已经过优化(仅针对主键进行搜索)。

索引字段怎么样?

索引字段不保证要过滤的值的唯一性,可能会出现多次。所以LIMIT 1是有道理的,假设你想要返回一行。

答案 1 :(得分:4)

如果该字段上有唯一索引,我根本看不到这种改进的执行时间 - 即使是微优化标准也是如此。

然而,我可以看到它可能掩盖了其他问题。假设您将LIMIT 1添加到这些查询中,然后以某种方式,您查询的字段将丢失其唯一索引,并且db将获得具有相同值的多行。这段代码将继续愉快地进行 - 我认为你可能想要快速失败,以便意识到(并修复)更大的潜在问题。

在我自己的db接口代码中,我有一个方法queryOneRow(),它运行一些SQL并在它返回多行时引发异常。对我来说,最有意义的是在应用层显式处理它,而不是在SQL中进行防御。

答案 2 :(得分:1)

在我查询唯一字段的大多数情况下,我仍然使用LIMIT 1。我主要这样做是因为我想确保无论人们对数据库/表做什么,我的查询都不会返回或操作多行。

通常这也应该包含动态格式错误的查询以弄乱整个数据库(并且不 - 我不是在谈论SQL注入)。

答案 3 :(得分:0)

由于查询只会在任何给定时刻返回一条记录;然后添加LIMIT 1不会增加执行时间。

我不确定MySQL使用哪种算法来执行LIMIT 1次请求。但具有讽刺意味的是,它可能使用比较表达式或迭代器只返回1条记录 - 在这种情况下,LIMIT 1的添加实际上可能延迟执行时间

答案 4 :(得分:0)

简短答案: 如果您要搜索索引唯一字段:没有区别。

但是请注意: 如果您针对不唯一字段进行搜索:将LIMIT 1添加到查询中将使您受益匪浅。即使您在该字段上有索引。

例如,如果您在email字段中没有唯一索引

SELECT * FROM users WHERE email="user@example.com" LIMIT 1

将比

更快
SELECT * FROM users WHERE email="user@example.com"

即使两个查询都将返回一条记录。

这是因为一旦找到一条记录,MySQL将停止搜索更多记录。