纯SQL
自2008年以来情况发生了变化。您可以使用窗口函数在一个查询中获取全部计数 和 有限的结果。009年PostgreSQL
8.4中引入。
SELECt foo , **count(*) OVER() AS full_count**FROM barWHERe <some condition>ORDER BY <some col>LIMIT <pagesize>OFFSET <offset>;
请注意,这 可能比没有总数要贵得多 。必须对所有行进行计数,可能的快捷方式仅从匹配索引中获取最前面的行可能不再有用。
小表或
full_count<=
OFFSET+ 没关系
LIMIT。事关重大
full_count。
__
OFFSET极端 情况 :当至少等于基本查询的行数时, 不 返回 任何行
。所以你也没有
full_count。可能的选择:
SELECT
查询中的事件顺序
(0. CTE是分别评估和实现的。在Postgres 12或更高版本中,计划者可以在上班之前内联那些子查询。)
WHERe
子句(和JOIN
条件,尽管您的示例中没有条件)从基表中筛选合格的行。 其余部分基于过滤后的子集。
(2.
GROUP BY和聚合函数将放在此处。)不在此处。
(3.
SELECT根据分组/聚合的列评估其他列表表达式。)此处不行。
窗口函数的应用取决于
OVER
子句和函数的框架规范。简单count(*) OVER()
基于所有合格行。ORDER BY
(6.
DISTINCT否则
DISTINCT ON会去这里。)不在这里。
LIMIT
/OFFSET
将基于已建立的顺序应用以选择要返回的行。
LIMIT/
OFFSET随着表中行数的增加,效率越来越低。如果需要更好的性能,请考虑其他方法:
获得最终计数的替代方法
有完全不同的方法来获取受影响的行的计数(
不是
OFFSET&之前的全部计数
LIMIT)。Postgres内部记录了上一条SQL命令影响了多少行。一些客户端可以访问该信息或自己计算行数(例如psql)。
例如,使用以下命令执行SQL命令后,可以立即在 plpgsql中 检索受影响的行数:
GET DIAGNOSTICS integer_var = ROW_COUNT;
或者您可以
pg_num_rows在 PHP中使用。或其他客户端中的类似功能。



