Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

các cách để tránh các bảng tạm thời toàn cục trong oracle

Trước tiên hãy trả lời câu hỏi thứ hai:

"tại sao lại rời xa GTT? chúng thực sự tệ như vậy."

Vài ngày trước, tôi đã tạo ra một bằng chứng về khái niệm tải một tệp XML lớn (~ 18MB) vào một XMLType. Bởi vì tôi không muốn lưu trữ XMLType vĩnh viễn, tôi đã thử tải nó vào một biến PL / SQL (bộ nhớ phiên) và một bảng tạm thời. Việc tải nó vào một bảng tạm thời lâu gấp 5 lần khi tải nó vào một biến XMLType (5 giây so với 1 giây). Sự khác biệt là do các bảng tạm thời không phải là cấu trúc bộ nhớ:chúng được ghi vào đĩa (cụ thể là vùng bảng tạm thời được chỉ định của bạn).

Nếu bạn muốn lưu vào bộ nhớ cache nhiều dữ liệu thì việc lưu trữ trong bộ nhớ sẽ gây căng thẳng cho PGA, điều này sẽ không tốt nếu bạn có nhiều phiên. Vì vậy, đó là sự đánh đổi giữa RAM và thời gian.

Đối với câu hỏi đầu tiên:

"Ai đó có thể chỉ cách chuyển các truy vấn mẫu ở trên thành bộ sưu tập và / hoặc con trỏ không?"

Các truy vấn bạn đăng có thể được hợp nhất thành một câu lệnh duy nhất:

SELECT case when a.column_a IS NULL OR a.column_a = ' ' 
           then b.data_a
           else  column_a end AS someA,
       a.someB,
       a.someC
FROM TABLE_A a
      left outer join TABLE_B b
          on ( a.column_b = b.data_b AND a.column_c = 'C' )
WHERE condition_1 = 'YN756'
  AND type_cd = 'P'
  AND TO_NUMBER(TO_CHAR(m_date, 'MM')) = '12'
  AND (lname LIKE (v_LnameUpper || '%') OR
  lname LIKE (v_searchLnameLower || '%'))
  AND (e_flag = 'Y' OR
  it_flag = 'Y' OR
  fit_flag = 'Y'));

(Tôi chỉ đơn giản là chuyển đổi logic của bạn nhưng case() đó có thể thay thế câu lệnh bằng nvl2(trim(a.column_a), a.column_a, b.data_a) ).

Tôi biết bạn nói rằng các truy vấn của bạn phức tạp hơn nhưng cổng gọi đầu tiên của bạn nên xem xét viết lại chúng. Tôi biết việc chia một truy vấn gnarly thành rất nhiều SQL con được kết hợp với nhau với PL / SQL nhưng SQL thuần hiệu quả hơn thì hiệu quả hơn thế nào.

Để sử dụng một tập hợp, cách tốt nhất là xác định các kiểu trong SQL, vì nó cho phép chúng ta sử dụng chúng trong các câu lệnh SQL cũng như PL / SQL một cách linh hoạt.

create or replace type tab_a_row as object
    (col_a number
     , col_b varchar2(23)
     , col_c date);
/
create or replace type tab_a_nt as table of tab_a_row;
/

Đây là một hàm mẫu, trả về một tập kết quả:

create or replace function get_table_a 
      (p_arg in number) 
      return sys_refcursor 
is 
    tab_a_recs tab_a_nt; 
    rv sys_refcursor; 
begin 
    select tab_a_row(col_a, col_b, col_c)  
    bulk collect into tab_a_recs 
    from table_a 
    where col_a = p_arg; 

    for i in tab_a_recs.first()..tab_a_recs.last() 
    loop 
        if tab_a_recs(i).col_b is null 
        then 
            tab_a_recs(i).col_b :=  'something'; 
        end if; 
    end loop;  

    open rv for select * from table(tab_a_recs); 
    return rv; 
end; 
/ 

Và nó đang hoạt động ở đây:

SQL> select * from table_a
  2  /

     COL_A COL_B                   COL_C
---------- ----------------------- ---------
         1 whatever                13-JUN-10
         1                         12-JUN-10

SQL> var rc refcursor
SQL> exec :rc := get_table_a(1)

PL/SQL procedure successfully completed.

SQL> print rc

     COL_A COL_B                   COL_C
---------- ----------------------- ---------
         1 whatever                13-JUN-10
         1 something               12-JUN-10

SQL>

Trong hàm, cần phải khởi tạo kiểu với các cột, để tránh ngoại lệ ORA-00947. Điều này là không cần thiết khi điền một loại bảng PL / SQL:

SQL> create or replace procedure pop_table_a
  2        (p_arg in number)
  3  is
  4      type table_a_nt is table of table_a%rowtype;
  5      tab_a_recs table_a_nt;
  6  begin
  7      select *
  8      bulk collect into tab_a_recs
  9      from table_a
 10      where col_a = p_arg;
 11  end;
 12  /

Procedure created.

SQL> 

Cuối cùng là hướng dẫn

"Hướng dẫn sử dụng Whento là gì và Khi nào nên tránh sử dụng GTT"

Bảng tạm thời toàn cục rất tốt khi chúng ta cần chia sẻ dữ liệu đã lưu trong bộ đệm giữa các đơn vị chương trình khác nhau trong cùng một phiên. Ví dụ:nếu chúng ta có cấu trúc báo cáo chung được tạo bởi một hàm duy nhất cung cấp GTT được điền bởi một trong số các thủ tục. (Mặc dù điều đó cũng có thể được thực hiện với con trỏ tham chiếu động ...)

Các bảng tạm thời toàn cục cũng tốt nếu chúng ta có nhiều quá trình xử lý trung gian quá phức tạp để có thể giải quyết bằng một truy vấn SQL duy nhất. Đặc biệt nếu quá trình xử lý đó phải được áp dụng cho các tập con của các hàng được truy xuất.

Nhưng nói chung, giả định nên là chúng ta không cần sử dụng một bảng tạm thời. Vì vậy,

  1. Làm điều đó trong SQL trừ khi quá khó, trường hợp này ...
  2. ... Làm điều đó trong các biến PL / SQL (thường là bộ sưu tập) trừ khi nó chiếm quá nhiều bộ nhớ, trong trường hợp đó ...
  3. ... Làm điều đó với Bảng Tạm thời Toàn cục


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Trình điều khiển Oracle ODBC của bạn tải ứng dụng khách Oracle như thế nào?

  2. Có Oracle tương đương với OUTPUT INSERTED của SQL Server. * Không?

  3. Bắt đầu viết blog cho HTML5 và CSS3

  4. Cách tạo một thủ tục bên trong một gói trong Oracle

  5. Cách loại bỏ số 0 khi Phần nguyên là số 0 trong Oracle