表具有從序列生成的替代主鍵。不幸的是,這個序列用於生成一些其他表的鍵(我沒有設計它,我不能改變它)。在表中選擇`n`最後插入記錄 - oracle
什麼是最快的方式來選擇最後n
插入的記錄在Oracle中,按ID降序排列(最後插入頂部)?
n
是一些比較小的數 - 要在頁面上顯示的記錄數 - 可能不大於50
表現擁有30.000.000記錄10-15數以千計的新記錄每天。
數據庫是Oracle 10g。
編輯:
在回答一個評論:這個問題與執行計劃的動機查詢:
select * from MyTable order by primarykeyfield desc
執行計劃是:
我感到驚訝的是Oracle希望在排序字段上有索引時執行全表掃描和排序。
從接受的答案查詢使用索引,並避免排序。
編輯2:
Re。 APC的評論:排序是讓我感到驚訝的一部分。我預計Oracle會使用索引按預期順序檢索行。查詢執行計劃:
select * from (select * from arh_promjene order by promjena_id desc) x
where rownum < 50000000
使用索引來代替全表訪問和排序(通知條件rownum < 50.000.000
- 這是後超過在表中的記錄數和Oracle知道它應該從表中檢索所有記錄)。此查詢返回的所有行的第一個查詢,但下面執行計劃:
| Id | Operation | Name |
-------------------------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | COUNT STOPKEY | |
| 2 | VIEW | |
| 3 | TABLE ACCESS BY INDEX ROWID| MyTable |
| 4 | INDEX FULL SCAN DESCENDING| SYS_C008809 |
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<50000000)
這是不尋常的,我認爲甲骨文正在爲這兩個查詢,基本上返回相同的結果集不同的執行計劃。
編輯3: 重新Amoq的評論:
Oracle不知道50M比行數更大 。當然, 它有統計數據,但它們可能是 舊的和錯誤的 - 並且Oracle從不會 允許自己發送錯誤的 結果,只是因爲統計信息是 錯誤。
確定嗎?在最多9個Oracle版本中,建議不時手動刷新統計數據。由於版本10 Oracle自動更新統計信息。如果Oracle不將它用於查詢優化,那麼統計數據的用途是什麼?
爲什麼不幸的是,序列也用於其他表?查詢檢索最後n個插入的記錄並不重要,因爲一個序列永遠不會被Oracle無條件地取消。所以你不能在max-n和max之間做一個簡單的id。 – tuinstoel 2009-12-01 19:00:06
您的查詢爲* all *行選擇* all *列。爲什麼你對Oracle進行全面的表掃描感到驚訝?否則它會如何獲得數據以滿足該查詢? – APC 2009-12-02 11:11:31
Oracle不知道* 50M是否大於行數。當然,它有統計數據,但它們可能是老的和錯誤的 - 並且Oracle只會因爲統計數據錯誤而不會允許自己提供不正確的結果。 – 2009-12-02 12:19:25