swx*_*xii 34 mysql sql indexing performance limit
例如,我在一个我知道将是唯一的字段上查询并被索引,例如主键.因此我知道这个查询只返回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
如果字段被索引,是否会添加改进查询执行时间?
OMG*_*ies 40
在使用LIMIT 1
针对主键或唯一约束的过滤条件查询时使用不是一种好的做法.主键或唯一约束意味着表中只有一个行/记录具有该值,只返回一行/记录.LIMIT 1
在主键/唯一字段上存在矛盾- 稍后维护代码的人可能会误认为重要并且猜测您的代码.
但最终的指标是解释计划:
explain SELECT t.name FROM USERS t WHERE t.userid = 4
Run Code Online (Sandbox Code Playgroud)
...的回报:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
-----------------------------------------------------------------------------------------------------
1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 |
Run Code Online (Sandbox Code Playgroud)
...和:
explain SELECT t.name FROM USERS t WHERE t.userid = 4 LIMIT 1
Run Code Online (Sandbox Code Playgroud)
...的回报:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
-----------------------------------------------------------------------------------------------------
1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 |
Run Code Online (Sandbox Code Playgroud)
没有区别,没有必要.在这种情况下似乎已经优化(仅针对主键进行搜索).
索引字段不保证被过滤值的唯一性,可能会出现多次.所以LIMIT 1
有意义,假设你想要返回一行.
如果该字段上有唯一索引,我根本看不到执行时间的改善 - 即使按照微优化标准,这也是一个延伸。
然而,我可以看到它可能掩盖其他问题。假设您向这些查询添加 LIMIT 1,然后您正在查询的字段会以某种方式丢失其唯一索引,并且数据库会获取具有相同值的多行。这段代码将继续愉快地运行 - 我认为您可能希望快速失败,以意识到(并修复)更大的潜在问题。
在我自己的数据库接口代码中,我有一个方法 queryOneRow() ,它运行一些 SQL 并在返回多于一行时抛出异常。对我来说,在应用程序层显式处理这个问题而不是在 SQL 中防御性地处理这个问题最有意义。
归档时间: |
|
查看次数: |
5199 次 |
最近记录: |