2012-10-14 61 views
1
select * from (
select t_tmp_a.*, rownum t_tmp_id from (
select t.*, i.counts 
from table1 t, (select id, count(id) counts from table2 group by id) i 
where t.id=i.id and t.kindid in (0,1,3) order by t.id desc 
) t_tmp_a where rownum <= 20) t_tmp_b where t_tmp_id >= 11; 

表1和表2中每个表超过2万个数据,当执行这个查询需要18S,在此之前的查询执行在大约7秒就要计算总数的需要,所以它花费超过25秒以上,任何想要优化它吗?Oracle数据寻呼优化

+1

Probablly是http://dba.stackexchange.com/问题。 – hkutluay

+0

@Mat,对不起,我有这个问题发布到该网站。 – user1744739

+0

@Mat感谢您的警告..从现在开始我不知道旗帜功能。 – hkutluay

回答

1

分页通常是一种向人类显示结果的机制。没有人想要读取200万行数据。

因此,如果这个查询确实将行呈现给真人,那么您需要解决的问题是将整个结果的大小减小到人的大小。因此,您需要在数据库中应用其他过滤器并返回一个重点结果集。您的用户不仅会感谢您,您的网络管理员也会如此。另一方面,如果此数据洪水的预期收件人是计算机或其他机械设备,那么就把它全部给它吧。机器大多不关心网页,或者如果他们(电子表格,打印机等),他们有内置的子例程来处理我们分页。


因此,我们的问题是您的原始查询需要很长时间才能执行。没有任何解释计划或统计信息(table1中有多少行符合搜索条件?kindid的这些值有多大限制?),这很难解决。

“kindid是这样一种类型,只有三个选择(0,1,3)”

Fnord。如果KINDID只能有三个的选择,那么在WHERE子句中使用它的意义何在?

事实上,从WHERE子句中删除它可能会显着提高查询的性能。除非你已经收集到该列的直方图,否则Oracle会假定in (0,1,3)会以某种方式限制结果集;而如果大多数行在该列中有NULL,则这只会是真的。如果是这种情况,最好使用kindid is not null

+0

是的,我同意,结果显示给人类,也许我应该在第一次访问时添加默认时间过滤器,如果用户添加他们的过滤器,我应该抛弃默认过滤器,如果我使用正确的方式? – user1744739

+0

table1也是大约200万行,将来会有更多,kindid是只有三种选择(0,1,3)的类型。 @APC – user1744739