以下内部SELECT返回大量行(1000000+),外部SELECTs(alpha BETWEEN #startRec#AND#endRec#)用于PAGINATION 显示每页25个数据。
问题是: - 以下完成的PAGINATION非常缓慢并且减缓了整个数据的显示。所以请大家帮忙我这样做 以更好的方式分页?关于分页的编码最好。
**我很抱歉这样做,但我对分页概念很新,所以需要你的帮助。
/*********ORIGINAL QUERY ****/
SELECT
*
FROM
(
SELECT
beta.*, rownum as alpha
FROM
(
SELECT
p.lastname, p.firstname, porg.DEPARTMENT,
porg.org_relationship,
porg.enterprise_name,
(
SELECT
count(*)
FROM
test_person p, test_contact c1, test_org_person porg
WHERE
p.p_id = c1.ref_id(+)
AND p.p_id = porg.o_p_id
$where_clause$
) AS results
FROM
test_person p, test_contact c1, test_org_person porg
WHERE
p.p_id = c1.ref_id(+)
AND p.p_id = porg.o_p_id
$where_clause$
ORDER BY
upper(p.lastname), upper(p.firstname)
) beta
)
WHERE
alpha BETWEEN #startRec# AND #endRec#
我在下面尝试过的实现
(1)最内层查询..是第一个QUERY获取数据。 (2)然后,我们对上述数据进行总计COUNT。
现在,主要问题是运行查询继续进行....最后我必须强行取消它。 我觉得下面的查询中有一些东西丢失了。
另外,我开始知道在外面做COUNT是性能最好的方法。所以,请你更正下面的查询,以便我能够返回COUNT ***使用分页,rownum等数据。主要使用下面的别名,rownum和获取数据。
select * from
( select x.* ,rownum rnum
from ( SELECT
count(*) as results /****2nd QUERY is OUTSIDE to get total count**/
问题在这里,我如何访问下面第一个查询中选择的数据
from ( /****1st query to SELECT data***/
SELECT
p.lastname, p.firstname, porg.DEPARTMENT,
porg.org_relationship,
porg.enterprise_name
FROM
t_person p, t_contact c1, t_o_person porg
WHERE rownum <10
and
p.person_id = c1.ref_id(+)
AND p.person_id = porg.o_person_id
ORDER BY
upper(p.lastname), upper(p.firstname)
) y ------------------>alias defined Y from data of the 1st query
)x ------------------>alias defined X
where rownum <= 20 )
where rnum >= 1
答案 0 :(得分:2)
要快速进行分页,您需要限制返回的查询结果。例如。在mysql中,您可以使用limit和calc_rows。
您必须检查您的数据库,但如果您没有这些帮助程序功能,那么将这些数据分解为单独的查询会更容易。
答案 1 :(得分:2)
也许我错过了什么,但你有没有考虑使用LIMIT和OFFSET条款? http://www.sql.org/sql-database/postgresql/manual/queries-limit.html
答案 2 :(得分:1)
我通常将此作为两个单独的查询,例如:
-- get page of data
SELECT *
FROM
(
SELECT
p.lastname, p.firstname, porg.DEPARTMENT,
porg.org_relationship,
porg.enterprise_name
FROM
test_person p, test_contact c1, test_org_person porg
WHERE
p.p_id = c1.ref_id(+)
AND p.p_id = porg.o_p_id
$where_clause$
ORDER BY
upper(p.lastname), upper(p.firstname)
) beta
WHERE
rownum BETWEEN #startRec# AND #endRec#
--get total count
SELECT count(*) as Count
FROM
test_person p, test_contact c1, test_org_person porg
WHERE
p.p_id = c1.ref_id(+)
AND p.p_id = porg.o_p_id
$where_clause$
您还可以返回结果中第一行数据的总计数,如下所示:
SELECT null, null, null, null, null, count(*) as Count
FROM
test_person p, test_contact c1, test_org_person porg
WHERE
p.p_id = c1.ref_id(+)
AND p.p_id = porg.o_p_id
$where_clause$
UNION ALL
SELECT *
FROM
(
SELECT
p.lastname, p.firstname, porg.DEPARTMENT,
porg.org_relationship,
porg.enterprise_name, null
FROM
test_person p, test_contact c1, test_org_person porg
WHERE
p.p_id = c1.ref_id(+)
AND p.p_id = porg.o_p_id
$where_clause$
ORDER BY
upper(p.lastname), upper(p.firstname)
) beta
WHERE
rownum BETWEEN #startRec# AND #endRec#
答案 3 :(得分:1)
您使用的数据库是什么?如果Oracle其他人建议的想法不起作用,Oracle不支持SQL的LIMIT
语法。
对于Oracle,您可以使用以下语法包装查询:
SELECT *
FROM (SELECT a.*,
ROWNUM rnum
FROM ( [your query] ) a
WHERE ROWNUM <= [endRow] )
WHERE rnum >= [startRow]
答案 4 :(得分:0)
这些专门用于ASP,但可以轻松修改: http://databases.aspfaq.com/database/how-do-i-page-through-a-recordset.html 就个人而言,当我最近需要一个分页解决方案时,我实现了“#Temp table”存储过程方法。
答案 5 :(得分:0)
我的建议是:
我怀疑必须首先解析内部子查询,如果没有合适的索引,那就太贵了。通常按计算列排序不使用索引,创建时态表等等。
干杯
答案 6 :(得分:0)
在Oracle中有几个选项:
Tom Kyte已经很好地描述了这两种方法:
http://www.oracle.com/technology/oramag/oracle/07-jan/o17asktom.html
希望这有帮助。