获取有限集合时获取记录总数 - Oracle

时间:2009-08-11 22:17:30

标签: sql oracle

我在下面的查询中根据特定条件获取500条记录。事实上有很多行(数百万)。我想得到记录的总数,所以我可以说“显示500行......”。我可以使用此查询执行此操作吗?目前我有单独的查询来做到这一点,但我想知道我是否可以在同一查询中做到这一点。

干杯,

查询:

SELECT * FROM APPL_PERF_STATS 
WHERE (GENERIC_METHOD_NAME != 'NULL' AND CURRENT_APPL_ID != 'NULL' AND EVENT_NAME != 'NULL')  
AND ROWNUM <  500 
AND current_appl_id  LIKE '%OrderingGUI%' 
AND event_name  LIKE '%/ccui%' 
AND generic_method_name  LIKE '%com.telus.customermgt.service.CustomerMgtSvc.getCustomer%' AND appl_perf_interval_typ_id = 1440 
AND cover_period_start_ts >= to_date('06-07-2008 11:53','dd-mm-yyyy HH24:mi') 
AND cover_period_start_ts <= to_date('11-08-2009 11:53','dd-mm-yyyy HH24:mi')  
ORDER BY CURRENT_APPL_ID, EVENT_NAME, GENERIC_METHOD_NAME, CREATE_TS 

6 个答案:

答案 0 :(得分:5)

在实践中,当我遇到这样的问题时,我通常会选择一个比我愿意显示的更多(比如500,所以拉501),如果我达到这个数量,那么告诉用户“返回了500多条记录“这使用户能够优化查询。您可以先运行查询计数,然后返回前n行,但这需要再次访问服务器,并且根据查询复杂性和数据量,可能需要很长时间。

另一种方法是在统计表中添加计数,您可以在执行此查询之前对其进行总结。理论上,您的统计表将保存比主表少得多的数据,因此可以快速地由服务器进行处理。如果您编写一个进程(存储过程最有效)来更新这些进程,然后返回结果。

我不确定您的应用程序或您的用户。但是我的一般要么不关心记录总量,要么只想记录总量而不想要细节。

答案 1 :(得分:4)

在Oracle中,至少可以使用分析函数来完成此任务:

例如:

  select
      count(*) over (partition by null) total_num_items,
      p.*
  from
      APPL_PERF_STATS p
  where
      ...

请注意(如APC所述)在使用ROWNUM将输出限制为 n 行之前,您需要在子查询中嵌入有序查询。

虽然这是获取返回结果集中总行数的方法,但在后台Oracle将计算所有行。因此,如果存在“数百万行”,则会出现性能损失。如果性能损失过大,我使用的方法是将总行数预先聚合为单独的批处理作业。如果是这种情况,您可能会发现物化视图很有用。

答案 2 :(得分:2)

ORDER BY和ROWNUM不会以您认为他们互动的方式进行互动。首先应用ROWNUM:

SQL> select ename from emp
  2  where rownum < 5
  3  order by ename
  4  /

ENAME
----------
CLARKE
PADFIELD
ROBERTSON
VAN WIJK

SQL> select * from (
  2     select ename from emp
  3     order by ename
  4  )
  5  where rownum < 5
  6  /

ENAME
----------
BILLINGTON
BOEHMER
CAVE
CLARKE

SQL>

答案 3 :(得分:2)

显示第1页的100 的愿望来自对Google的过度曝光。与其他领域一样,Google所做的与企业IT无关。谷歌猜测,但它的架构使其猜测相当准确。

如果您使用的是开箱即​​用的RDBMS,则设置不正确。你必须通过执行两个查询来做到这一点 - 一个用于获取计数,一个用于获取行。如果查询编入索引,那么执行初始计数可能不会太昂贵,但它仍然是两个查询。

答案 4 :(得分:2)

SELECT rn, total_rows, x.OWNER, x.object_name, x.object_type
  FROM (SELECT COUNT (*) OVER (PARTITION BY owner) AS TOTAL_ROWS,
               ROW_NUMBER () OVER (ORDER BY 1) AS rn, uo.*
          FROM all_objects uo
         WHERE owner = 'CSEIS') x
 WHERE rn BETWEEN 6 AND 10

RN  TOTAL_ROWS  OWNER   OBJECT_NAME     OBJECT_TYPE
6   1262        CSEIS   CG$BDS_MODIFICATION_TYPES       TRIGGER
7   1262        CSEIS   CG$AUS_MODIFICATION_TYPES       TRIGGER
8   1262        CSEIS   CG$BDR_MODIFICATION_TYPES       TRIGGER
9   1262        CSEIS   CG$ADS_MODIFICATION_TYPES       TRIGGER
10  1262        CSEIS   CG$BIS_LANGUAGES                TRIGGER

答案 5 :(得分:0)

在实践中,我发现拥有这样的数据几乎没有帮助 - 而且价格昂贵。特别是如果正在写入表格,您的总计数会不断变化,因此向用户显示一个非常不可靠的数字。