IndexedDB游标本身不加速检索,仅支持有序遍历;真正实现毫秒级查询需为常用字段建索引(如byOrderNo),模糊搜索则须结合倒排索引与Web Worker预处理,游标仅用于结果ID读取。

IndexedDB 游标本身不是为“快速检索”设计的,而是为**有序遍历**服务的。在十万级数据中直接用游标 逐条匹配(比如 cursor.continue() 配合 if (item.name.includes(keyword)))本质上仍是 O(n) 全量扫描,性能不会比数组 filter 好多少——这恰恰是很多项目卡顿的根源。
用索引代替游标遍历
游标快不快,取决于它是否走索引、走的是哪种索引:
- 只对主键(
keyPath)使用游标,只能按插入顺序或 key 升序/降序遍历,无法加速字段搜索; - 必须为常用查询字段(如
orderNo、status、createdAt)单独创建 multiEntry 索引 或 compound 索引; - 例如搜索订单号:建索引
db.createObjectStore('orders', { keyPath: 'id' }).createIndex('byOrderNo', 'orderNo', { unique: true }),再用index.openCursor(IDBKeyRange.only('ORD-2026-XXXX'))—— 这才是毫秒级定位; - 模糊搜索(如“包含某字符串”)不能靠普通索引,需配合倒排索引 + Web Worker 预处理,游标只用于读取结果 ID 列表。
避免游标阻塞主线程
即使走索引,大量数据的游标遍历(如导出全部、统计总数)仍会同步占用主线程:
- 不要在一个事务里一次性遍历全部匹配项;
- 改用分页式游标:每次
openCursor(range, 'next')只取 100–500 条,处理完再递归调用,中间用setTimeout或queueMicrotask让出主线程; - 对纯计算型操作(如求和、计数),优先用 IndexedDB 的
count()方法,它底层优化过,比手动游标累加快得多。
数据结构适配索引能力
IndexedDB 的索引不支持表达式、不支持大小写无关匹配、不支持分词,所以数据存入前就要“对齐”索引能力:
- 需要按日期范围查?把
createdAt存成时间戳数字,而非 Date 对象或字符串; - 需要忽略大小写搜索?存数据时额外加一个
searchNameLower字段,索引建在它上面; - 需要多字段联合筛选?用 compound 索引,如
createIndex('byStatusAndTime', ['status', 'createdAt']),查询时必须按顺序提供 range。
冷热分离 + 预聚合
十万行不是所有数据都同等重要:
- 高频访问的近期数据(如最近 30 天订单)单独建 store,搭配细粒度索引;
- 历史数据归档到另一个 store,只保留摘要字段(如按天聚合的订单数、总金额),用简单索引即可满足统计需求;
- 把常查的聚合结果(如“待发货订单共 2387 条”)缓存在一个独立 objectStore 中,定期由后台任务更新,查询时直取,绕过游标。











