问题描述
纯sql
自2008年以来情况发生了变化。您可以使用窗口函数在一个查询中获取全部计数 和 有限的结果。2009年PostgreSQL 8.4中引入。
SELECT foo
, **count(*) OVER() AS full_count**
FROM bar
WHERE <some condition>
ORDER BY <some col>
LIMIT <pagesize>
OFFSET <offset>;
请注意, ,这 。必须对所有行进行计数,可能的快捷方式仅从匹配的索引中获取最前面的行可能不再有用。
小表或full_count
<= OFFSET
+没关系LIMIT
。事关重大full_count
。
:当至少等于基本查询的行数时, _ 返回 _
。所以你也没有full_count
。可能的替代方法:
SELECT
查询中的事件顺序
(0. CTE是分别评估和实现的。在Postgres 12或更高版本中,计划者可以在上班之前内联诸如子查询之类的东西。)
-
WHERE
子句(和JOIN
条件,尽管您的示例中没有条件)从基表中筛选合格的行。
(2.GROUP BY
和聚合函数将放在此处。)不在此处。
(3.SELECT
基于分组/聚合的列评估其他列表表达式。)此处不行。
(6.disTINCT
否则disTINCT ON
会去这里。)不在这里。
-
LIMIT
/OFFSET
是基于已建立的顺序应用的,以选择要返回的行。
LIMIT
/OFFSET
随着表中行数的增加,效率变得越来越低。
获得最终计数的替代方法
有完全不同的方法来获取受影响的行的计数( _
_OFFSET
&之前的全部计数LIMIT
)。Postgres具有内部记帐功能,其中最后一个sql命令影响了多少行。一些客户端可以访问该信息或自己计算行数(例如psql)。
例如,使用以下命令执行sql命令后,可以立即在 检索受影响的行数:
GET DIAGNOSTICS integer_var = ROW_COUNT;
或者您可以pg_num_rows
在 使用。或其他客户端中的类似功能。
解决方法
当分页来自数据库的数据时,您需要知道将要呈现多少页来呈现页面跳转控件。
目前,我通过运行两次查询来做到这一点,一次包裹在a中count()
以确定总结果,第二次使用限制以仅获取我当前页面所需的结果。
这似乎效率低下。有没有更好的方法来确定在LIMIT
应用之前将返回多少结果?
我正在使用PHP和Postgres。