2010-01-25 57 views
6

我与99896618.甲骨文和分页

我需要获取数据的小块(可以说100条记录),以显示它在网页上的记录数的Oracle表,(在网络世界我们称它为分页)。目前,我正在使用以下查询来完成该操作,但用户对性能不满意。

SELECT * FROM (select rownum rnum,f.* from findings f where rownum<90000100) 
        WHERE rnum > 90000000 

目前需要1分22秒才能得到结果。无论如何要让它变得更好。我当然愿意提供任何类型的建议,包括修改表结构或像添加索引。

(仅供参考,我使用ASP.NET作为服务器端的web技术和ADO.NET作为客户端呈现的数据访问层和Silverlight)

回答

6

您的查询将需要计算第一个90M记录才能获得下一个100,所以几乎没有改进的余地。

我在你的子查询中没有看到ORDER BY子句,但可能你有它。在这种情况下,您可能需要在其上创建索引。

还有一个问题:用户在抱怨性能之前是否真的点击了900K页面?

更新:

如果您需要最新页面,你需要重写你的ORDER BY列按降序:

SELECT * 
FROM (
     SELECT rownum rnum, f.* 
     FROM findings f 
     ORDER BY 
       record_ordering_column DESC 
     ) 
WHERE rnum > 900 
     AND rownum <= 100 

和创建record_ordering_column

注意的指标,我从嵌套查询中混合使用rownum以提高性能。

请参阅本文中我的博客更多的细节:

+0

通过创建页码的下拉列表,我可以轻松访问页码(只是简单的描述,我创建了一个自定义控件,通过它们可以轻松访问最后1000页)。 可能这是有用的信息,大部分时间(大约95%的时间)用户对最后(最新)记录感兴趣。 – funwithcoding 2010-01-25 17:26:07

1

如果你愿意修改表我会建议您将一个rownumber列添加到表(使用插入触发器和序列来设置它),然后向该列添加索引。

+0

Oracle中没有非集群或聚集索引 - 它们只是称为索引。 – 2010-01-25 17:15:05

+0

'@OMG Ponies':是的,但'Oracle'中有索引的集群! :) – Quassnoi 2010-01-25 17:17:28

+0

@OMG小马:主键是oracle中的聚集索引,并且所有没有主键索引都是非聚簇的。你一定在谈论我知道在oracle中不存在的'nonclustered' *关键字*。 – 2010-01-25 17:18:28

5

从您的意见之一:%的时间

大部分的时间(约95 )用户对最后(最新)记录感兴趣

在这种情况下,为什么不以相反顺序显示记录,以便95%的用户对页面1感兴趣,而不是页面900,000?

如果他们真的希望看到“900,000页”,那意味着他们很早就对数据感兴趣,所以允许他们通过例如过滤数据来过滤数据。日期范围。只是在没有任何过滤的情况下分页1亿行是永远不会被执行的。

0

你是否真的需要整行回来?这意味着你没有使用任何索引。

如果你仍然需要整行。请使用以下模式:

SELECT * FROM findings f1 WHERE f1.rowid IN 
    (SELECT rownum rnum, row_id 
     FROM (
      SELECT f.rowid row_id 
       FROM findings f 
      ORDER BY record_ordering_column 
      ) 
    WHERE rownum > 900 
    ) 
WHERE rnum <= 100; 

注:微妙的额外SELECT子句以及使用ROWID查询。

如果您在record_ordering_column上添加索引,则该异教会使用该索引来获取一组ROWID。然后只加载包含由其ROWID标识的行的块。

这会比您当前的查询更好,它将成为全表扫描。