eri*_*ric 5 sql sql-server pagination orientdb keyset
高性能分页的常见解决方案是使用索引字段,从前一页的最后一个值开始每个新“页面”。例如,对于这样的数据集(假设 Category 和 ID 是主键):
Category | ID | Name
Red | 10 | Bob Jones
Red | 14 | Sam Smith
Red | 16 | Jill White
Blue | 10 | Mike Green
Blue | 16 | Mary Brown
Run Code Online (Sandbox Code Playgroud)
假设(相当小的)页面大小为 1,如果我们要返回所有Red类别记录(假设 ORDER BY Category, ID):
SELECT * FROM table WHERE Category='Red' AND ID>'00' (1st page, returns Bob Jones)
SELECT * FROM table WHERE Category='Red' AND ID>'10' (2nd page, returns Sam Smith)
SELECT * FROM table WHERE Category='Red' AND ID>'14' (3rd page, returns Jill White)
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为通过分页“keyset”只使用 ID 字段(如果 ID 是全局唯一的,它也可以在多个字段上工作,而事实并非如此)。
但是如果我想返回所有的红色和蓝色记录(假设该表还包含其他类别),仍然一次一页(假设 ORDER BY Category, ID):
SELECT * FROM table WHERE Category IN ['Red', 'Blue'] AND Category>'' AND ID>'00' (1st page, returns Bob Jones)
SELECT * FROM table WHERE Category IN ['Red', 'Blue'] AND Category>'Red' AND ID>'10' (2nd page, returns Sam Smith, but skips Mike Green)
Run Code Online (Sandbox Code Playgroud)
在 PostgreSQL 和其他一些中,有一个“行值”谓词语法支持这个(假设 ORDER BY Category, ID):
SELECT * FROM table WHERE (Category, ID) > ('', '00') (1st page, returns Bob Jones)
SELECT * FROM table WHERE (Category, ID) > ('Red', '10') (2nd page, returns Sam Smith)
Run Code Online (Sandbox Code Playgroud)
它之所以有效,是因为出于测试目的,类别和 ID 都被视为单个复合值。但我没有使用 PostgreSQL 或支持“行值”的数据库。所以问题是是否有替代解决方案适用于此(是否有 2 个或 n 个字段)?为了使其适用于多个变量字段的分页,我需要设置一个谓词,该谓词将始终在多字段排序顺序中找到“下一条记录”。
PS:OFFSET/LIMIT 或 SKIP/LIMIT 分页当然有效,但在大型数据集上都没有效率,这就是我尝试使用“keyset”分页的原因。
您始终可以对谓词进行措辞:
(x, y) > (a, b)
Run Code Online (Sandbox Code Playgroud)
作为:
x >= a and (x = a and y > b or x > a)
Run Code Online (Sandbox Code Playgroud)
请注意,第一个谓词x >= a促进(它不确保)在该列上使用索引。也就是说,它变成了“访问谓词”。第二个x = a and y > b or x > a过滤掉多余的行,有效地成为“过滤谓词”。
这种表述“元组不等式”谓词的方式促进了索引的使用。但是,如果您比较 3、4 或更多列,它们会变得越来越复杂。
扩展The Impaler's answer,使用复合键的键集分页的通用语法如下:
WHERE
(x > a) OR
(x = a AND y > b) OR
(x = a AND y = b AND z > c) OR
...
Run Code Online (Sandbox Code Playgroud)
这不如 好(x, y, z) > (a, b, c),但您可以使用您选择的语言生成 SQL。您遍历复合字段集并扩展每个连续字段以包括{field} = {value} AND 先前的字段。
| 归档时间: |
|
| 查看次数: |
781 次 |
| 最近记录: |