indexeddb高效查询必须依赖索引,索引只能在onupgradeneeded中创建且需升级版本号;应按高频查询字段建单字段、复合或多值索引,并显式通过idbkeyrange调用索引方法。

IndexedDB 本身不支持 SQL 式的“WHERE”查询,所有非主键字段的高效检索都依赖索引。没有索引时,哪怕只查 1000 条数据中的某几条,也得遍历整个对象仓库——这在万级数据下会明显卡顿甚至阻塞主线程。真正提升检索性能的关键,是提前建好、用对索引。
索引必须在 onupgradeneeded 中创建
索引不是运行时可添加的配置,它属于数据库结构的一部分。只有在版本升级触发 onupgradeneeded 时,才能调用 createIndex()。如果跳过这步,后续任何查询都无法走索引路径。
- 每次修改索引(新增、重命名、删除)都需提升数据库版本号,否则旧结构不会更新
- 已存在的对象仓库不能直接加索引,必须先检查
db.objectStoreNames.contains('storeName'),再创建 - 索引名必须全局唯一,同一仓库内不能有两个同名索引
按高频查询字段建索引,不盲目堆砌
索引加快读取,但会增加写入开销和存储占用。重点为那些你真正在代码里反复用来过滤或排序的字段建索引,比如 status、category、createdAt、userId。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 单字段索引:如
store.createIndex('by-status', 'status', { unique: false }) - 复合索引:适合组合条件,如
['type', 'priority'],但注意范围查询只对最左前缀生效 - 多值索引(
multiEntry: true):适用于字段值是数组的情况,例如tags: ['js', 'db'],会为每个元素分别建索引项
查询时必须显式使用索引 + IDBKeyRange
建了索引不代表自动生效。你得主动获取索引对象,再调用它的方法(如 get()、getAll() 或 openCursor()),并传入 IDBKeyRange 定义条件。
- 精确匹配:
index.get(IDBKeyRange.only('active')) - 范围查询:
index.getAll(IDBKeyRange.bound('2025-01-01', '2025-12-31')) - 流式遍历(防内存溢出):
index.openCursor(IDBKeyRange.lowerBound(100)) - 不要用
objectStore.getAll()后再 JS 过滤——那等于放弃索引优势
避免常见误用导致索引失效
即使索引存在,写法不对也会退化成全量扫描。
- 对字符串做模糊前缀查询时,不能用
.includes(),而要用IDBKeyRange.bound('abc', 'abd')利用字典序 - 复合索引中,若只按第二个字段查(如
['date', 'amount']中只查amount > 100),索引无法命中 - 索引字段值为
null或undefined时,默认不被索引收录,需设{ unique: false }并确保数据一致性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










