Bảng có khóa chính thay thế được tạo ra từ trình tự. Thật không may, trình tự này được sử dụng để tạo khóa cho một số bảng khác (tôi đã không thiết kế nó và tôi không thể thay đổi nó).Chọn `n` các bản ghi được chèn cuối cùng trong bảng - oracle
Cách nhanh nhất để chọn n
bản ghi được chèn vào cuối cùng trong Oracle, được sắp xếp theo id theo thứ tự giảm dần (lần chèn cuối cùng ở trên cùng) là gì?
n
là một số lượng tương đối nhỏ - số lượng hồ sơ để hiển thị trên trang - có lẽ không lớn hơn 50.
Bảng hiện có 30.000.000 hồ sơ với 10-15 ngàn kỷ lục mới hàng ngày.
Cơ sở dữ liệu là Oracle 10g.
Edit:
Trong câu trả lời cho một lời nhận xét: Câu hỏi này đã được thúc đẩy với kế hoạch thực hiện cho truy vấn:
select * from MyTable order by primarykeyfield desc
kế hoạch thực hiện là:
---------------------------------------------
| Id | Operation | Name |
---------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT ORDER BY | |
| 2 | TABLE ACCESS FULL| MyTable |
---------------------------------------------
Tôi rất ngạc nhiên rằng Oracle muốn để thực hiện quét toàn bộ bảng và sắp xếp khi nó có chỉ mục trên trường sắp xếp.
Truy vấn từ câu trả lời được chấp nhận sử dụng chỉ mục và tránh sắp xếp.
Chỉnh sửa 2:
Re. Nhận xét của APC: Phân loại là một phần khiến tôi ngạc nhiên. Tôi hy vọng rằng Oracle sẽ sử dụng chỉ mục để lấy các hàng theo thứ tự mong muốn. kế hoạch thực hiện cho truy vấn:
select * from (select * from arh_promjene order by promjena_id desc) x
where rownum < 50000000
sử dụng chỉ số thay vì truy cập bảng đầy đủ và sắp xếp (thông báo tình trạng rownum < 50.000.000
- đây là cách nhiều hơn số lượng các bản ghi trong bảng và Oracle đều biết rằng nó nên lấy tất cả hồ sơ từ bảng). Truy vấn này trả về tất cả các hàng như truy vấn đầu tiên, nhưng với kế hoạch thực hiện như sau:
| 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)
Nó là không bình thường với tôi rằng Oracle đang tạo ra kế hoạch thực hiện khác nhau cho hai truy vấn này mà về cơ bản trở cùng tập kết quả.
Sửa 3: Cảm nhận Re Amoq của:
Oracle không biết 50M đó là lớn hơn số hàng. Chắc chắn, nó có thống kê, nhưng chúng có thể là cũ và sai - và Oracle sẽ không bao giờ cho phép chính nó cung cấp kết quả không chính xác chỉ vì số liệu thống kê là sai.
Bạn có chắc chắn không? Trong các phiên bản Oracle lên đến 9 nó được khuyến khích để làm mới số liệu thống kê theo cách thủ công theo thời gian. Kể từ phiên bản 10 Oracle tự động cập nhật số liệu thống kê. Việc sử dụng dữ liệu thống kê là gì nếu Oracle không sử dụng nó để tối ưu hóa truy vấn?
Tại sao không may là trình tự cũng được sử dụng cho các bảng khác? Nó không quan trọng đối với truy vấn để lấy ra các bản ghi được chèn n mới nhất bởi vì một chuỗi không bao giờ được kiểm duyệt để không bị mất khoảng cách bởi Oracle. Vì vậy, bạn không thể làm một đơn giản, nơi id giữa max-n và max anyway. – tuinstoel
Truy vấn của bạn chọn * tất cả * cột cho * tất cả * hàng. Tại sao bạn ngạc nhiên rằng Oracle thực hiện quét bảng ful? Làm cách nào khác để nhận dữ liệu để đáp ứng truy vấn đó? – APC
Oracle không * biết * rằng 50M lớn hơn số hàng. Chắc chắn, nó có số liệu thống kê, nhưng chúng có thể cũ và sai - và Oracle sẽ * không bao giờ * cho phép bản thân cung cấp kết quả không chính xác chỉ vì số liệu thống kê sai. –