2012-10-14 57 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