为何WHERE idx = ?比WHERE prop_link = ?执行更快?SQLite3更新性能疑问
为什么两条UPDATE语句性能差这么大?
这问题我太熟了!本质就是索引在SQLite查询中的核心作用,正好对应你猜的哈希/二分查找逻辑——咱们一步步拆解:
先看毫秒级完成的那条:UPDATE addresses SET full_street = ? WHERE idx = ?
idx是INTEGER PRIMARY KEY,SQLite会自动给主键创建聚集索引(Clustered Index),这种索引的底层是平衡二叉树(B-tree)结构。查找时用二分查找思路,时间复杂度是O(log n):1亿行数据的话,log₂(100,000,000)大概是27次比对,瞬间就能定位到目标行。- 更关键的是,聚集索引的叶子节点直接存储整行数据,找到索引键后不用再去别的地方找数据,直接就能更新,没有额外的IO开销,这就是它快到毫秒级的原因。
再看慢到“冻结”的那条:UPDATE addresses SET full_street = ? WHERE prop_link = ?
- 你的
prop_link是普通TEXT列,而且没有创建索引,这时候SQLite只能做全表扫描(Full Table Scan):从表的第一行开始,逐行比对prop_link的值,直到找到匹配的行。1亿行数据意味着要遍历所有记录,这个过程需要读取大量磁盘数据(内存根本装不下1亿行),IO成本极高,所以会出现“等待数小时仍无响应”的情况——不是代码卡住了,是数据库在拼命读磁盘。 - 你猜的哈希表/二分查找其实对应索引的两种常见实现:哈希索引适合等值查询,而SQLite默认用B-tree索引(既支持等值也支持范围查询)。如果给
prop_link建个索引,数据库就能用二分查找快速定位,性能会和主键查询差不多。
解决办法:给prop_link创建索引
执行这条SQL语句创建索引:
CREATE INDEX idx_addresses_prop_link ON addresses(prop_link);
- 索引创建完成后,再执行
UPDATE ... WHERE prop_link = ?,速度会直接提升到毫秒级。 - 注意:如果
prop_link有大量重复值,或者你频繁更新这个列,索引会带来一些维护开销,但对于你用它做更新条件的场景,这个开销完全可以忽略。
内容的提问来源于stack exchange,提问作者Query
相关产品推荐
相关产品推荐

