rya*_*e28 2 javascript python sql database postgresql
我在处理数据库时并不迷失,但也不是专家。
我想在我的网站上实现无限滚动,这意味着数据需要按 date_created 或 id 降序排列。我最初的想法是在这样的查询中使用 LIMIT 和 OFFSET (使用 SQLalchemy):
session.query(Posts).filter(Posts.owner_id == _userid_).filter(Posts.id < post_id).orderBy(desc(Posts.id)).limit(5).all()
Run Code Online (Sandbox Code Playgroud)
翻译成这样:
SELECT * from posts WHERE owner_id = _userid_ AND id < _post_id_ ORDER BY id DESC LIMIT 10 OFFSET _somevalue_;
Run Code Online (Sandbox Code Playgroud)
在我的js中:
var minimum_post_id = 0;
var posts_list = [];
var post_ids = [];
function infinite_load(_userid_, _post_id_) {
fetch('/users/' + _userid_ + '/posts/' + _post_id_)
.then(r => r.json())
.then(data => {
console.log(data);
data.posts.forEach(post => { posts_list.push(post); post_ids.push(post.id) });
minimum_post_id = Math.min(...post_ids);
})
}
infinite_load(1, minimum_post_id) // random user id
Run Code Online (Sandbox Code Playgroud)
然而,我正在研究这是否有效并遇到了这个: https: //www.eversql.com/faster-pagination-in-mysql-why-order-by-with-limit-and-offset-is-慢的/
基本上,它是说限制和偏移是不好的,因为它仍然必须计算所有要偏移的记录,然后将它们丢弃。
所以我的问题是,我的实施是否不够充分?如何有效地顺序查询数据库?
分页——正确完成——比简单的“我们在上一页显示什么 id 范围?添加 10 来限制和偏移”有更多的倒刺。一些简单的问题来激发您的兴趣,然后是一个建议:
当用户查看位置为 11 到 20 的项目时,会在位置 15 处插入一条记录。单击“下一步”分页按钮后,会向用户返回什么?
相反,当用户查看位置从 101 到 110 的记录时,位置 100 以下的任意 10 个记录将被删除。单击“下一步”分页后,用户会得到什么?或者点击“上一页”分页?
根据您的数据模型、架构和 UI 要求,这些问题可能很简单,也可能很难回答。
现在,为什么 LIMIT/OFFSET 是错误的方法......实际上,只要你有一个足够小的数据集——而且对于大多数网站来说这可能很大。换句话说,选择适合您的设置的方法。
同时,对于在“非常大”的数据集假设下具有教学思想的人来说:OFFSET 是该查询的杀手部分(因为它需要对结果进行统计、排序、计数,然后在 LIMIT 生效之前跳过) 。那么,我们如何去除OFFSET呢?将其合并到查询的 CONSTRAINT 部分。
您的查询按 ID 排序,然后按某个数字进行偏移。通过确保 ID 大于(或小于)当前屏幕为用户显示的 ID 来删除偏移量:
SELECT * FROM posts
WHERE
owner_id = _userid_
AND id < _last_displayed_id
ORDER BY id DESC
LIMIT 10;
Run Code Online (Sandbox Code Playgroud)
同样,如果您按时间排序,则使分页按钮(或滚动处理程序)在已呈现给用户的最后一个项目之后/之前请求新记录。
| 归档时间: |
|
| 查看次数: |
1537 次 |
| 最近记录: |