Bảng tạm thời giống như bảng trong bộ nhớ nhờ vào bộ nhớ đệm và I / O không đồng bộ và giải pháp bảng tạm thời không yêu cầu bất kỳ chi phí nào để chuyển đổi giữa SQL và PL / SQL.
Xác nhận kết quả
So sánh hai phiên bản với RunStats, phiên bản bảng tạm thời trông tệ hơn nhiều. Tất cả rác cho phiên bản bảng tạm thời trong Run1 và chỉ một ít bộ nhớ bổ sung cho phiên bản PL / SQL trong Run2. Lúc đầu, có vẻ như PL / SQL sẽ là người chiến thắng rõ ràng.
Type Name Run1 (temp) Run2 (PLSQL) Diff
----- -------------------------------- ------------ ------------ ------------
...
STAT physical read bytes 81,920 0 -81,920
STAT physical read total bytes 81,920 0 -81,920
LATCH cache buffers chains 104,663 462 -104,201
STAT session uga memory 445,488 681,016 235,528
STAT KTFB alloc space (block) 2,097,152 0 -2,097,152
STAT undo change vector size 2,350,188 0 -2,350,188
STAT redo size 2,804,516 0 -2,804,516
STAT temp space allocated (bytes) 12,582,912 0 -12,582,912
STAT table scan rows gotten 15,499,845 0 -15,499,845
STAT session pga memory 196,608 19,857,408 19,660,800
STAT logical read bytes from cache 299,958,272 0 -299,958,272
Nhưng vào cuối ngày, chỉ có thời gian trên đồng hồ treo tường mới là vấn đề quan trọng. Cả bước tải và bước truy vấn đều chạy nhanh hơn nhiều với các bảng tạm thời.
Phiên bản PL / SQL có thể được cải thiện bằng cách thay thế BULK COLLECT
với cast(collect(test_o(MOD(a, 10), '' || MOD(a, 12))) as test_t) INTO t
. Nhưng nó vẫn chậm hơn đáng kể so với phiên bản bảng tạm thời.
Đọc được tối ưu hóa
Việc đọc từ bảng tạm thời nhỏ chỉ sử dụng bộ đệm đệm nằm trong bộ nhớ. Chỉ chạy phần truy vấn nhiều lần và xem cách consistent gets from cache
(bộ nhớ) tăng trong khi physical reads cache
(đĩa) giữ nguyên.
select name, value
from v$sysstat
where name in ('db block gets from cache', 'consistent gets from cache',
'physical reads cache');
Viết được tối ưu hóa
Lý tưởng nhất là sẽ không có I / O vật lý, đặc biệt vì bảng tạm thời là ON COMMIT DELETE ROWS
. Và có vẻ như phiên bản tiếp theo của Oracle có thể giới thiệu một cơ chế như vậy. Nhưng nó không quan trọng lắm trong trường hợp này, I / O đĩa dường như không làm chậm mọi thứ.
Chạy bước tải nhiều lần, rồi chạy select * from v$active_session_history order by sample_time desc;
. Hầu hết I / O là BACKGROUND
, có nghĩa là không có gì đang chờ đợi trên đó. Tôi giả sử logic nội bộ bảng tạm thời chỉ là một bản sao của các cơ chế DML thông thường. Nói chung, dữ liệu bảng mới có thể cần được ghi vào đĩa, nếu nó được cam kết. Oracle có thể bắt đầu làm việc với nó, chẳng hạn như bằng cách di chuyển dữ liệu từ bộ đệm nhật ký sang đĩa, nhưng không cần vội cho đến khi có COMMIT
thực tế .
Thời gian PL / SQL trôi đi đâu?
Tôi không có đầu mối. Có nhiều chuyển đổi ngữ cảnh hoặc một chuyển đổi duy nhất giữa các công cụ SQL và PL / SQL không? Theo như tôi biết, không có số liệu nào có sẵn hiển thị thời gian đã dành cho việc chuyển đổi giữa SQL và PL / SQL.
Chúng tôi có thể không bao giờ biết chính xác tại sao mã PL / SQL chậm hơn. Tôi không lo lắng về nó quá nhiều. Câu trả lời chung là, phần lớn công việc cơ sở dữ liệu phải được thực hiện trong SQL. Sẽ rất có ý nghĩa nếu Oracle dành nhiều thời gian hơn để tối ưu hóa cốt lõi của cơ sở dữ liệu của họ, SQL, hơn là ngôn ngữ bổ trợ, PL / SQL.
Ghi chú bổ sung
Để kiểm tra hiệu suất, có thể hữu ích nếu xóa connect by
logic thành một bước riêng biệt. SQL đó là một thủ thuật tuyệt vời để tải dữ liệu, nhưng nó có thể rất chậm và tốn nhiều tài nguyên. Thực tế hơn là tải một bảng mẫu một lần bằng thủ thuật đó, rồi chèn từ bảng đó.
Tôi đã thử sử dụng tính năng Oracle 12c mới, hoàn tác tạm thời và tính năng 18c mới, các bảng tạm thời riêng tư. Không một bảng nào được cải thiện hiệu suất so với các bảng tạm thời thông thường.
Tôi sẽ không đặt cược vào nó, nhưng tôi có thể thấy một cách mà kết quả sẽ hoàn toàn thay đổi khi dữ liệu lớn hơn. Bộ đệm nhật ký và bộ đệm đệm chỉ có thể lớn như vậy. Và cuối cùng I / O nền đó có thể cộng dồn và lấn át một số quy trình, biến BACKGROUND
đợi vào FOREGROUND
Chờ đợi. Mặt khác, chỉ có quá nhiều bộ nhớ PGA cho giải pháp PL / SQL, và sau đó mọi thứ sẽ sụp đổ.
Cuối cùng, điều này phần nào xác nhận sự hoài nghi của tôi về "cơ sở dữ liệu trong bộ nhớ". Lưu vào bộ nhớ đệm không có gì mới, cơ sở dữ liệu đã hoạt động trong nhiều thập kỷ.