unicloud云数据库仅自动为_id字段及控制台手动启用索引的字段建索引,where中其他字段(如created_at、type)不会自动建索引,需手动创建单字段或按等值在前、范围在后的顺序创建复合索引,并确保lookup的localfield和foreignfield字段均有索引。

uniCloud云数据库确实会自动创建索引,但“自动”不等于“全覆盖”,很多查询变慢、where条件失效、甚至报 Query not supported 错误,根源往往就出在索引没被自动命中——你得知道它什么时候管用、什么时候不管用。
哪些字段会自动建索引?
uniCloud只对两类字段无条件建索引:
-
_id字段(必有,主键) - 你在控制台「集合设置」里手动勾选了「启用索引」的字段(比如
user_id、status)
注意:where 查询中用到的其他字段,比如 db.collection('orders').where({ created_at: { $gt: timestamp } }) 中的 created_at,不会自动建索引,哪怕你反复查它,系统也不会“学习”并补上索引。
为什么 where 查询很慢却没报错?
这是最易踩的坑:没有索引的 where 查询会触发全表扫描,数据量一过几千条,响应就明显延迟,但云数据库默认不报错,只默默变慢。你看到的 db.collection('logs').where({ type: 'error' }).get() 耗时 2s+,大概率就是 type 字段没索引。
- 验证方法:在云数据库控制台 → 对应集合 → 「索引管理」里查有没有
type_1这样的索引项 - 临时补救:手动添加单字段索引,类型选
ascending(升序即可,除非你要$lt+sort混用) - 别依赖“以后再加”:上线前就把高频查询字段列出来,一次性建好
复合索引怎么写才生效?
当你写 where({ category: 'book', status: 'published', created_at: { $gte: t } }),单建 category 或 status 索引都没用,必须建复合索引,且顺序关键:
- 等值字段放前面(
category、status) - 范围字段放最后(
created_at) - 正确索引名示例:
category_1_status_1_created_at_1 - 错误写法:
created_at_1_category_1—— 范围字段在前,后面等值字段索引失效
如果查询还带 .orderBy('updated_at'),那复合索引还得把 updated_at 加到最后,否则排序仍会内存排序,可能超内存限制。
lookup 关联查询为啥总超时?
lookup 不是 SQL 的 JOIN,它本质是两次查询 + 内存合并。如果被关联集合(比如 users)没在 localField 对应字段(如 user_id)上建索引,第一次查主表快,第二次查关联表就会全表扫——500 条数据就可能超时。
- 必须确保:所有
localField和foreignField字段都已单独建索引 - 例如:
db.collection('orders').aggregate().lookup({ from: 'users', localField: 'user_id', foreignField: 'uid' })→user_id和uid都得有索引 - 别省这一步:控制台里点「索引管理」→「新建索引」→ 输入字段名 → 保存
自动索引只保底,真要稳,每个 where 条件、每个 lookup 字段、每个 orderBy 字段,都得亲手确认索引存在——它不会猜你要什么,只会按你明说的建。











