lancedb 0.15 里给每个租户写同一个表,靠 tenant_id 区分,检索写成 table.search(vec).where("tenant_id = 't1'").limit(5),返回的五条里混着两个 t2 的文档,把 where 换成双引号反而报 SQL 语法错。
排查方向其实有限,先把可能性排一排。tenant_id 写入时是整数,过滤条件用了字符串比较;limit 在过滤之前生效,先截断再筛导致候选不足;向量列和标量列不在同一批写入,部分行 tenant_id 为空;查询走了旧的数据版本,新写入还没 compact。
动手时先看过滤列的真实类型和空值数量
python -c "import lancedb;t=lancedb.connect('./lance_db').open_table('docs');print(t.count_rows(\"tenant_id is null\"));print(t.schema)"
接着按类型改写条件并打开预过滤
python -c "import lancedb;print(lancedb.connect('./lance_db').open_table('docs').search([0.1]*1024).where('tenant_id = 1').limit(5).to_list())"
给 tenant_id 建标量索引再测一次延迟
python -c "import lancedb;lancedb.connect('./lance_db').open_table('docs').create_scalar_index('tenant_id')"
等前面都确认过,再把 null 行补齐后 compact 一次
python -c "import lancedb;lancedb.connect('./lance_db').open_table('docs').compact_files()"
改完先别撤,确认这几项。同样查询返回的五条 tenant_id 全为 t1,count_rows 里空值归零,检索延迟从 400 毫秒降到 120 毫秒。
提醒一点。租户隔离不能只靠一句 where,字段类型、空值和索引三处都要对齐,最稳的做法是每个租户一张表,隔离交给目录层而不是查询条件。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
