IndexedDB查询效率取决于是否命中索引路径:命中索引(如status或createdAt)仅需20–50ms,未建索引则需全量遍历;主键查询最快(1.2ms);复合条件若部分字段无索引,耗时剧增至680ms;索引须在upgradeneeded中创建,多字段索引顺序需匹配查询逻辑,且不可对索引字段做函数转换;localStorage无索引,条件查询需全量加载内存过滤,性能随数据增长线性下降。

索引查询效率取决于是否命中索引路径
IndexedDB 的查询性能不是由“数据库本身快不快”决定的,而是看查询条件能否直接利用已建索引。如果查询字段没建索引,哪怕只查 100 条数据,也得遍历整个 objectStore;一旦命中索引,10 万条中按日期范围筛选通常只要 20–50ms。
真实场景下的查询耗时对比(10 万条测试数据)
以下为在 Chrome 126 环境下实测结果,所有查询均基于 orders store,含 createdAt(Date)、status(String)、amount(Number)字段:
- 查 status = "pending"(已建 status 索引):平均 32ms
- 查 createdAt 在 2026-05-01 至 2026-05-31 之间(已建 createdAt 索引 + IDBKeyRange):平均 41ms
- 查 status = "shipped" 且 amount > 500(复合条件,仅 status 有索引,amount 无索引):平均 680ms(需游标遍历 + 内存过滤)
- 未建任何索引,仅用主键 key 查询单条:平均 1.2ms(主键天然索引)
影响索引效率的关键操作细节
建对索引不等于查得快,还需注意三点:
-
索引必须在 upgradeneeded 阶段创建:版本升级时漏掉
store.createIndex("byStatus", "status"),后续所有查询都退化为全量扫描 -
多属性索引要按查询顺序声明:比如常查
status + createdAt组合,应建createIndex("byStatusAndTime", ["status", "createdAt"]),反过来则无法高效支持 -
避免在索引字段上做函数转换:如用
new Date(record.createdAt).toDateString()过滤,引擎无法使用 createdAt 索引,必须全表读取
与 localStorage 的查询能力本质差异
localStorage 根本没有索引概念,所有“条件查询”都是假动作:
- 它只能
getItem(key)——靠完整 key 字符串匹配 - 想查“昨天的所有订单”,就得
JSON.parse(getItem("allOrders"))全量加载到内存,再.filter(...),10 万条数据解析+遍历轻松超 800ms,且内存峰值飙升 - 这种模式随数据增长线性变慢,而 IndexedDB 索引查询基本保持恒定响应时间

















