例如,我正在查询我知道将是唯一的字段并且已编入索引,例如主键。因此我知道这个查询只返回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
会改善查询执行时间?
答案 0 :(得分:39)
在使用针对主键或唯一约束的过滤条件查询时,使用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将停止搜索更多记录。