【发布时间】:2010-05-25 13:46:58
【问题描述】:
我正在使用 Oracle 10g 和以下范例来一次获得 15 个结果的页面(这样当用户查看搜索结果的第 2 页时,他们会看到记录 16-30)。
select *
from
( select rownum rnum, a.*
from (my_query) a
where rownum <= 30 )
where rnum > 15;
现在我必须运行一个单独的 SQL 语句来对“my_query”进行“选择计数”,以获取 my_query 的结果总数(以便我可以将其展示给用户并使用它找出总页数等)。
有没有什么方法可以在不通过第二个查询(即从上面的查询中获取)的情况下获取结果总数?我尝试添加“max(rownum)”,但它似乎不起作用(我收到一个错误 [ORA-01747],这似乎表明它不喜欢我在 group by 中包含关键字 rownum)。
我希望从原始查询中获取它而不是在单独的 SQL 语句中执行它的理由是“my_query”是一个昂贵的查询,所以我宁愿不运行它两次(一次获取计数,一次获取数据页面)如果我不需要;但是,如果可能的话,无论我想出什么解决方案来从单个查询中获取结果数量(同时获取我需要的数据页面),如果可能的话,不应该增加太多额外开销。请指教。
这正是我正在尝试做的事情,但我收到了 ORA-01747 错误,因为我认为它不喜欢我在 group by 中有 ROWNUM。请注意,如果有另一个解决方案不使用 max(ROWNUM),而是使用其他解决方案,那也很好。这个解决方案是我第一个想到的可能是什么。
SELECT * FROM (SELECT r.*, ROWNUM RNUM, max(ROWNUM)
FROM (SELECT t0.ABC_SEQ_ID AS c0, t0.FIRST_NAME, t0.LAST_NAME, t1.SCORE
FROM ABC t0, XYZ t1
WHERE (t0.XYZ_ID = 751) AND
t0.XYZ_ID = t1.XYZ_ID
ORDER BY t0.RANK ASC) r WHERE ROWNUM <= 30 GROUP BY r.*, ROWNUM) WHERE RNUM > 15
--------- 编辑 -------- 请注意,根据第一条评论,我尝试了以下似乎可行的方法。我不知道它与其他解决方案相比表现如何(我正在寻找满足我的要求但表现最好的解决方案)。例如,当我运行它时,它需要 16 秒。当我取出 COUNT(*) OVER () RESULT_COUNT 只需要 7 秒:
SELECT * FROM (SELECT r.*, ROWNUM RNUM, )
FROM (SELECT COUNT(*) OVER () RESULT_COUNT,
t0.ABC_SEQ_ID AS c0, t0.FIRST_NAME, t1.SCORE
FROM ABC t0, XYZ t1
WHERE (t0.XYZ_ID = 751) AND t0.XYZ_ID = t1.XYZ_ID
ORDER BY t0.RANK ASC) r WHERE ROWNUM <= 30) WHERE RNUM > 1
解释计划从执行 SORT (ORDER BY STOP KEY) 更改为执行 WINDOW (SORT)。
之前:
SELECT STATEMENT ()
COUNT (STOPKEY)
VIEW ()
SORT (ORDER BY STOPKEY)
NESTED LOOPS ()
TABLE ACCESS (BY INDEX ROWID) XYZ
INDEX (UNIQUE SCAN) XYZ_ID
TABLE ACCESS (FULL) ABC
之后:
SELECT STATEMENT ()
COUNT (STOPKEY)
VIEW ()
WINDOW (SORT)
NESTED LOOPS ()
TABLE ACCESS (BY INDEX ROWID) XYZ
INDEX (UNIQUE SCAN) XYZ_ID
TABLE ACCESS (FULL) ABC
【问题讨论】:
-
前几天,我看到有人使用
select a.*, count(*) over () from a ...来获取每一行的总数。巧妙的技巧,但我不知道如何在这里应用它:( -
我不确定这个查询是如何工作的,但如果它是相对静态的,你能不能得到一次计数并将其缓存在应用程序变量中,然后只在查询更改时重新计数?我不知道是否有一种方法可以在不实际计算所有记录的情况下获取结果集的计数。
-
当您有多个同样有效的建议时,您会怎么做?您应该在堆栈溢出时将哪一个标记为答案?
-
我猜是你最终用来解决问题的那个。或者至少是与您的解决方案更相似的那个。