Mik*_*iss 4 google-cloud-platform google-cloud-spanner
我有一个People表(Id, first_name, last_name),其中有主键id。我希望能够查找按 排序的表中的前 N 个人(last_name, first_name, Id)。在某些情况下,我需要查找接下来的 N 个人,等等。我想有效地做到这一点。做这个的最好方式是什么?
主要有两种方式:
LIMIT和OFFSETLIMIT上一页的使用和 key-of-previous-pageOFFSET 策略允许您读取任意页,但效率不高,因为每次运行查询时都必须读取所有先前页中的行。这是最容易实现的,也是一种可以接受的策略(特别是如果您只想要前几页),但一般情况下不建议这样做。前一页键策略确实要求按顺序读取页面,但效率更高,因为每个页面只读取它需要的行。
因此,让我们从原始查询开始,从按以下顺序排序的表中获取结果(LastName, FirstName, Id):
SELECT
t.id,
t.first_name,
t.last_name
FROM
People as t
ORDER BY
t.last_name,
t.first_name,
t.id
LIMIT
@limit_rows
Run Code Online (Sandbox Code Playgroud)
您可能希望确保所有查询都查看数据库数据的一致快照,因此您需要确保查询序列始终从相同的时间戳读取。实现此目的的最简单方法是将您的第一个查询设置returnReadTimestamp为 true 的 ReadOnly 事务。然后,您的后续查询也可以是只读事务,并且它们应该使用原始查询返回的相同时间戳作为它们的 readTimestamp。请注意,无论您选择什么方法,该ORDER BY子句对于确保查询序列中的结果一致至关重要。假设返回的最后一行是(1709, "John", "Smith")。然后,您第一次尝试查询以获得下一页结果可能如下所示:
SELECT
t.id,
t.first_name,
t.last_name
FROM
People as t
WHERE
t.last_name > "Smith"
OR
(t.last_name = "Smith" and t.first_name > "John")
OR
(t.last_name = "Smith" and t.first_name = "John" AND t.id > 1709)
ORDER BY
t.last_name,
t.first_name,
t.id
LIMIT
@limit_rows
Run Code Online (Sandbox Code Playgroud)
中间的WHERE条款是新的。但编写这个谓词比您想象的要棘手。您可能必须处理 NULL 值。您必须处理多个名为 John Smith 且具有不同价值观的人的情况id。您需要非常小心浮点数和NaN值。Cloud Spanner 的读取 API 在此类情况下也很有用,因为它可以更轻松地对表上的范围扫描进行分页。
| 归档时间: |
|
| 查看次数: |
3047 次 |
| 最近记录: |