[英]Is there any point using MySQL “LIMIT 1” when querying on indexed/unique field?
例如,我正在查询一个我知道将是唯一的字段,并且被索引,例如主键。 因此我知道这个查询只会返回 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
改善查询执行时间吗?
在使用针对主键或唯一约束的过滤条件进行查询时,使用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
是有道理的,假设你想返回一行。
如果该字段上有一个唯一索引,我根本看不到执行时间的改进——即使按照微优化标准,这也是一个延伸。
但是,我可以看到它可能掩盖了其他问题。 假设您将 LIMIT 1 添加到这些查询中,然后不知何故您查询的字段丢失了其唯一索引,并且数据库获得了具有相同值的多行。 这段代码将继续愉快地前进 - 我认为您可能希望快速失败,以意识到(并修复)更大的潜在问题。
在我自己的数据库接口代码中,我有一个方法 queryOneRow() 运行一些 SQL 并在返回多行时抛出异常。 对我来说,在应用程序层显式处理这个问题而不是在 SQL 中进行防御性处理最有意义。
在我查询唯一字段的大多数情况下,我仍然使用LIMIT 1
。 我这样做主要是因为我想确保无论任何人对数据库/表做什么,我的查询都不会返回或操作多于一行。
通常,这还应该涵盖动态格式错误的查询以弄乱整个数据库的情况(不 - 我不是在谈论 SQL 注入)。
由于查询只会在任何给定时刻返回一条记录; 那么添加LIMIT 1
不会增加您的执行时间。
我不确定 MySQL 使用哪种算法来执行LIMIT 1
请求。 然而具有讽刺意味的是,它可能使用比较表达式或迭代器只返回 1 条记录——在这种情况下, LIMIT 1
的添加实际上可能会延迟几条指令的执行时间。
简短回答:如果您正在搜索索引唯一字段:没有区别。
但是请注意:如果您针对非唯一字段进行搜索:您将受益于将LIMIT 1
添加到查询中。 即使您在该字段上有索引。
例如,如果您在email
字段上没有唯一索引
SELECT * FROM users WHERE email="user@example.com" LIMIT 1
将比
SELECT * FROM users WHERE email="user@example.com"
即使两个查询都将返回一条记录。
这是因为一旦找到一条记录,MySQL 将停止搜索更多记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.