sql >> Databáze >  >> RDS >> Oracle

Problém s proměnnými vazby Oracle, které správně nepoužívají index

Toto je skutečně rozsáhlejší téma, ale myslím si, že toto je přístup, který je nejjednodušší implementovat a funguje dobře. Trik je v použití dynamického SQL, ale implementovat jej tak, abyste vždy předali stejný počet parametrů (potřebných) A umožnili Oracle zkratovat, když nemáte hodnotu pro parametr (co vám chybí váš současný přístup). Například:

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;

Chcete-li otestovat, jednoduše jej spusťte. Například:

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

V mém systému používám tabulky více než 100 mm řádků s indexem v poli čísla a pole názvu. Vrátí se téměř okamžitě. Všimněte si také, že možná nebudete chtít vybrat *, pokud nepotřebujete všechny sloupce, ale jsem trochu líný a v tomto příkladu používám %rowtype.

Doufám, že to pomůže



  1. Převeďte desetinný čas na hodiny a minuty

  2. PŘIPOJIT SE k MySQL vs POUŽÍVAT?

  3. INSERT pomocí SELECT

  4. Jak použít SqlCommand k VYTVOŘENÍ DATABÁZE s parametrizovaným názvem db?