我有一個前N個查詢會給我帶來問題。訪問ID列表時前N個查詢性能
首先,我有如下所示的查詢:
select /*+ gather_plan_statistics */ * from
(
select rowid
from payer_subscription ps
where ps.subscription_status = :i_subscription_status
and ps.merchant_id = :merchant_id2
order by transaction_date desc
) where rownum <= :i_rowcount;
此查詢效果很好。通過使用merchant_id,subscription_status,transaction_date上的索引,它可以非常有效地找到大數據集的前10行。
-------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10 |00:00:00.01 | 4 |
|* 1 | COUNT STOPKEY | | 1 | | 10 |00:00:00.01 | 4 |
| 2 | VIEW | | 1 | 11 | 10 |00:00:00.01 | 4 |
|* 3 | INDEX RANGE SCAN DESCENDING| SODTEST2_IX | 1 | 100 | 10 |00:00:00.01 | 4 |
-------------------------------------------------------------------------------------------------------
正如您所見,每個階段估計的實際行數是10,這是正確的。
現在,我有一個要求,以獲得前N個記錄集merchant_Ids的,所以如果我更改查詢包括兩個merchant_ids,性能坦克:
select /*+ gather_plan_statistics */ * from
(
select rowid
from payer_subscription ps
where ps.subscription_status = :i_subscription_status
and (ps.merchant_id = :merchant_id or
ps.merchant_id = :merchant_id2)
order by transaction_date desc
) where rownum <= :i_rowcount;
----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 10 |00:00:00.17 | 178 | | | |
|* 1 | COUNT STOPKEY | | 1 | | 10 |00:00:00.17 | 178 | | | |
| 2 | VIEW | | 1 | 200 | 10 |00:00:00.17 | 178 | | | |
|* 3 | SORT ORDER BY STOPKEY| | 1 | 200 | 10 |00:00:00.17 | 178 | 2048 | 2048 | 2048 (0)|
| 4 | INLIST ITERATOR | | 1 | | 42385 |00:00:00.10 | 178 | | | |
|* 5 | INDEX RANGE SCAN | SODTEST2_IX | 2 | 200 | 42385 |00:00:00.06 | 178 | | | |
----------------------------------------------------------------------------------------------------------------------------
注意,現在有42K來自兩個索引範圍掃描的行 - Oracle在達到10行時不再放棄索引範圍掃描。我認爲會發生的事情是,Oracle會爲每個merchant_id獲取至多10行,因爲知道最多10行將被查詢返回。然後它會根據交易日期對10 + 10行進行排序並輸出前10,但拒絕這樣做。
有沒有人知道如何獲得第一個查詢的性能,當我需要將商家列表傳遞到查詢中時?我大概可以使用union來獲得性能,但商家列表是可變的,可以是1或2到100之間的任意值。
有趣。我一直在試圖改變這個計劃,但沒有任何影響。我聽起來像是一個潛在的選擇,如果我能夠實現它的話! – 2012-07-27 14:59:03
您是否嘗試在內部查詢中使用它? – jva 2012-07-27 15:01:43
是的,我在內外兩部分都試過了。 – 2012-07-27 15:07:55