在我的应用程序中,我有一个主题响应表。结构大致如下:
CREATE TABLE responses (
id INT NOT NULL PRIMARY KEY,
topic_id INT NOT NULL,
author_id INT NOT NULL,
response TEXT
);
id
是自增字段,topic_id
和author_id
是外键,有相应的索引等。
我总是想按插入时间排序,通常是最近的。在大多数情况下,我将按 topic_id
进行过滤。典型的查询如下所示:
SELECT * FROM responses WHERE topic_id=123 ORDER BY id DESC LIMIT 20;
-- or, for pagination:
SELECT * FROM responses WHERE topic_id=123 AND id < 456789 ORDER BY id DESC LIMIT 20;
我想实现一个黑名单 - 每个用户都有一个他们不想看到的 author_id
列表。我需要检索前 20 个结果,不包括那些 author_id
和回复它们的响应。
确定是否应排除一行非常复杂,虽然可能可以在数据库中执行此操作(在 PL/SQL 中或通过预处理),但我希望将逻辑保留在应用程序中。所以我可以做以下两件事之一:
- 忘记 LIMIT 子句,使查询不受限制。吃行直到我计算出 20 个有效结果,然后关闭查询。
- 应用分块 - 指定 LIMIT 40 并希望它足以获得 20 个“好”结果。如果没有,则获取接下来的 40 个,依此类推。
两者之间的实际区别是什么?特别是在许多并发用户的性能方面。
我在 PostgreSQL 中这样做,但我愿意切换到不同的 RDBMS。 (我不想失去参照完整性,所以我没有研究 NoSQL 解决方案)也许我必须调整数据库的一些参数(例如预取大小),以充分利用无限制的查询案例?
最佳答案
我不能说 Postgres 的细节,但查询优化器可能会使用 LIMIT 子句作为各种不同执行计划的成本计算的一部分。
如果你...
select ... from ... where ... limit n
然后优化器知道您将只检索 n 行,但是对于...
select ... from ... where ...
优化器可能会假设您需要整个结果集,估计可能有几千行。
特别是我希望 RDBMS 支持应用 LIMIT 子句的基于索引的访问方法。
关于postgresql - 使用 LIMIT 子句与简单地获取 N 个结果有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13294585/