【问题标题】:What is the most efficient way to find parents without childs on Google Spanner interleaved tables?在 Google Spanner 交错表上找到没有孩子的父母的最有效方法是什么?
【发布时间】:2022-09-24 09:37:03
【问题描述】:
我有两个非常大的表,它们的主键交错(只有一列,所以它是一对一的关系)。父表上的几行没有子表,我想找到它们。
目前,我正在执行 JOIN 查询并按 NULL 值搜索:
SELECT Users.userID
FROM Users
LEFT JOIN Licenses
ON Users.userID = Licenses.userID
WHERE Licenses.license IS NULL
但是这个查询仍然需要读取所有用户表来做 JOIN,真的很慢。
我知道,如果许可证列在用户表中,我可以用它创建一个索引,并且只需要读取具有 NULL 许可证值的行,但不能将列“许可证”放在同一“用户”表。
有没有办法使用不同的表通过尚未获得许可证的用户 ID?例如具有来自不同表的列的索引。 (我正在使用交错,但它会是更好的外键吗?)
标签:
performance
foreign-keys
google-cloud-spanner
gql
interleave
【解决方案1】:
澄清一下,以下是正确的理解吗?
- Users 表有主键 UserId
- Licenses 表有主键 UserId 和 license 列
- UserId 只能与 0 或 1 个许可证相关联
- 只有当 Licenses.license != NULL 时,Licenses 表才会有一行,因此 Licenses 中的行数 < Users 中的行数
- Users 和 Licenses 表都包含许多行
为了避免扫描用户表,也许许可证表甚至可以包括没有许可证的用户 ID。然后,可以创建 Licenses.license 索引以帮助搜索为 NULL 的许可证。
或者,当在用户中插入/删除用户 ID 和在许可证中插入/删除许可证时,应用程序可以跟踪其他状态。例如,跟踪包含所有没有许可证的 UserId 的 MissingLicense 表。 MissingLicense 表将有一个主键 UserId。在没有许可证的情况下插入 UserId 时,也要插入 MissingLicense。为用户插入许可证时,从 MissingLicense 中删除。从 Users 中删除 UserId 时,从 MissingLicense 中删除。 MissingLicense 可以在用户表下与 ON DELETE CASCADE 交错。