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

Sự cố với các biến liên kết của Oracle không sử dụng chỉ mục đúng cách

Đây thực sự là một chủ đề lớn hơn, nhưng đây là cách tiếp cận mà tôi nghĩ là dễ thực hiện nhất và hoạt động tốt. Bí quyết là sử dụng SQL động, nhưng triển khai nó để bạn luôn truyền cùng một số lượng tham số (cần thiết) VÀ bạn cho phép Oracle đoản mạch khi bạn không có giá trị cho một tham số (thứ bạn đang thiếu cách tiếp cận hiện tại của bạn). Ví dụ:

set serveroutput on
create or replace procedure test_param(p1 in number default null, p2 in varchar2 default null) as
  l_sql varchar2(4000);
  l_cur sys_refcursor;
  l_rec my_table%rowtype;
  l_ctr number := 0;
begin

  l_sql := 'select * from my_table where 1=1';
  if (p1 is not null) then
    l_sql := l_sql || ' and my_num_col = :p1';
  else
    -- short circuit for optimizer (1=1)
    l_sql := l_sql || ' and (1=1 or :p1 is null)';
  end if;

  if (p2 is not null) then
    l_sql := l_sql || ' and name like :p2';
  else
    -- short circuit for optimizer (1=1)
    l_sql := l_sql || ' and (1=1 or :p2 is null)';
  end if;

  -- show what the SQL query will be
  dbms_output.put_line(l_sql);

  -- note always have same param list (using)
  open l_cur for l_sql using p1,p2;

  -- could return this cursor (function), or simply print out first 10 rows here for testing
  loop
    l_ctr := l_ctr + 1;
    fetch l_cur
    into l_rec;
    exit when l_cur%notfound OR l_ctr > 10;

    dbms_output.put_line('Name is: ' || l_rec.name || ', Address is: ' || l_rec.address1);
  end loop;
  close l_cur;
end;

Để kiểm tra, chỉ cần chạy nó. Ví dụ:

set serveroutput on
-- using 0 param
exec test_param();
-- using 1 param
exec test_param(123456789);
-- using 2 params
exec test_param(123456789, 'ABC%');

Trên hệ thống của tôi, bảng được sử dụng là các hàng trên 100mm với chỉ mục trên trường số và trường tên. Trả về gần như ngay lập tức. Cũng lưu ý rằng bạn có thể không muốn thực hiện select * nếu bạn không cần tất cả các cột, nhưng tôi hơi lười và sử dụng% rowtype cho ví dụ này.

Hy vọng điều đó sẽ giúp



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Chia chuỗi theo vị trí dấu phân cách bằng SQL oracle

  2. Tại sao thời gian thực hiện thủ tục được lưu trữ trong oracle lại tăng lên rất nhiều tùy thuộc vào cách nó được thực thi?

  3. Biểu tượng nhà phát triển SQL

  4. Các phương pháp hay nhất:.NET:Làm thế nào để trả về PK với cơ sở dữ liệu oracle?

  5. Xóa các hàng trùng lặp trong bảng