uniCloud云数据库仅对_id字段和手动启用索引的字段自动建索引;其他where中使用的字段如created_at需手动创建索引,否则触发全表扫描导致查询变慢。

uni-app 本身不建索引,真正建索引的是 uniCloud 云数据库;没手动建,_id 以外的字段基本没索引,查得慢是常态,不是你代码写错了。
哪些字段会自动有索引?
uniCloud 只对两类字段“无条件”建索引:
-
_id字段(必有,系统自动生成) - 你在云控制台 → 集合 → 「集合设置」里手动勾选了「启用索引」的字段(比如
user_id、status)
其他所有你在 where 里用到的字段,比如 db.collection('orders').where({ created_at: { $gt: t } }) 中的 created_at,哪怕你每天查一万次,系统也不会自动补索引。这不是 bug,是设计如此。
查得慢但不报错?八成是缺索引
这是最隐蔽也最常见的性能陷阱:没有索引的查询会触发全表扫描,数据量一过 3000 条,get() 延迟就明显上升,但云数据库默认不抛错,只默默变慢。
- 验证方法:进云控制台 → 对应集合 → 「索引管理」,看有没有
type_1、status_1这类命名的索引项 - 临时补救:在「索引管理」里点「新建索引」,字段填
type,类型选ascending(升序即可,除非你要配合$lt+orderBy) - 别等上线后“再加”:把高频
where字段(如category、status、user_id)列出来,建库时一次性配好
复合索引怎么写才真生效?
当你写 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 关联查超时?先查 localField 和 foreignField 有没有索引
lookup 不是 SQL JOIN,它本质是两次独立查询 + 内存合并。如果被关联集合(比如 users)在 localField(如 user_id)上没索引,第一次查快,第二次查就会全表扫——500 条数据就可能超时。
- 必须确保:所有
localField和foreignField字段都已单独建好索引(哪怕只是单字段user_id_1) - 常见漏点:
db.collection('orders').aggregate().lookup({ from: 'users', localField: 'user_id', foreignField: 'uid' })→user_id和uid都要建索引 - 控制台索引管理里看不到对应索引项,就得立刻补
索引不是“加了就完事”,而是要和你的实际查询模式严丝合缝;where 怎么写,索引就怎么建,少一个字段、错一个顺序,都白搭。











