当前位置:  开发笔记 > 编程语言 > 正文

在应用LIMIT之前获得结果计数的最佳方法

如何解决《在应用LIMIT之前获得结果计数的最佳方法》经验,为你挑选了2个好方法。

分页来自数据库的数据时,您需要知道将有多少页面呈现页面跳转控件.

目前我通过运行查询两次,一次包装count()以确定总结果,第二次应用限制以获取当前页面所需的结果.

这似乎效率低下.有没有更好的方法来确定在LIMIT应用之前会返回多少结果?

我正在使用PHP和Postgres.



1> Erwin Brands..:

纯SQL

自2008年以来情况发生了变化.您可以使用窗口函数在一个查询中获取完整计数和有限结果.(2009年推出PostgreSQL 8.4).

SELECT foo
     , count(*) OVER() AS full_count
FROM   bar
WHERE  
ORDER  BY 
LIMIT  
OFFSET ;

请注意,这可能比没有总数更昂贵.必须对所有行进行计数,并且仅使用匹配索引中的顶行可能的快捷方式可能不再有用.
与小表或full_count<= OFFSET+ 无关LIMIT.事情要大得多full_count.

OFFSET极端情况:当至少与基本查询中的行数一样大时,返回任何行.所以你也没有full_count.可能的选择:

使用LIMIT/OFFSET运行查询,并获取总行数

考虑一系列事件:

    SELECT子句(和WHERE条件,但不是这里)过滤基表中的限定行.

    (JOIN和聚合函数会在这里.)

    考虑所有符合条件的行(取决于GROUP BY函数的子句和框架规范),应用窗口函数.简单SELECT基于所有行.

    OVER

    (count(*) OVER()或者ORDER BY会去这里.)

    DISTINCT/ DISTINCT ON根据建立的顺序应用,以选择要返回的行.

LIMIT/ OFFSET表中的行数越来越多,效率越来越低.如果您需要更好的性能,请考虑其他方法

在大表上使用OFFSET优化查询

获得最终计数的替代方案

有完全不同的方法来获得受影响的行数(完整的计数之前LIMITOFFSET被应用).Postgres具有内部簿记,受上一个SQL命令影响的行数.有些客户端可以访问该信息或自行计数行(如psql).

例如,您可以在执行SQL命令后立即检索plpgsql中受影响的行数:

GET DIAGNOSTICS integer_var = ROW_COUNT;

手册中的详细信息.

或者你可以OFFSETPHP中使用.或其他客户端中的类似功能.

有关:

计算PostgreSQL中受批处理查询影响的行数


在较旧版本的postgres中,您可以使用游标执行类似操作.例如`BEGIN; DECLARE c CURSOR FOR SELECT*FROM table; 向前迈进100 in c; FETCH 10 FROM c; 全力以赴; COMMIT;`.您可以从FETCH获取数据,并且可以根据需要从`pg_affected_rows`调用计算行数.

2> Grey Panther..:

正如我在博客中描述的那样,MySQL有一个名为SQL_CALC_FOUND_ROWS的功能.这消除了两次执行查询的需要,但它仍然需要完整地进行查询,即使limit子句允许它提前停止.

据我所知,PostgreSQL没有类似的功能.在进行分页时要注意的一件事(使用LIMIT最常见的事情是恕我直言):执行"OFFSET 1000 LIMIT 10"意味着数据库必须至少获取1010行,即使它只给你10分.更高效的方法是记住前一行(在本例中为1000)排序的行的值,并重写查询,如下所示:"... WHERE order_row> value_of_1000_th LIMIT 10".优点是"order_row"很可能被索引(如果没有,你就会出问题).缺点是如果在页面视图之间添加新元素,这可能会有点不同步(但是再一次,它可能无法被访问者观察到并且可以获得很大的性能提升).

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有