В данном же случае захотелось предостеречь от таких "оптимизаций" - не стоит лишний раз генерировать фулсканы даже если таблица сейчас маленькая... Да и решение само по себе крайне тривиально. Как говорится "вон из профессии" тем, кто до такого может не додуматься.
Вот для простого примерчика на табличке с 100тыс. записей и индексом по полю:
Elapsed | Consistent gets | |
---|---|---|
С разбиением значений | 00:00:00.01 | 7 |
С обратным like | 00:00:00.10 | 227 |
drop table t purge; create table t(str primary key) as select dbms_random.string('U',10) from dual connect by level<=1e5; exec dbms_stats.gather_table_stats(user,'t',cascade => true); column vals new_value find_us noprint; select listagg(str,',') within group(order by 1) vals from t sample(10) where rownum<=5; set serveroutput on autot on select * from t where t.str in ( select regexp_substr('&find_us','[^,]+',1,level) from dual connect by level<=regexp_count('&find_us','[^,]+') ); select * from t where '&find_us' like '%'||t.str||'%';
Comments
regexp_count в 10g нет.
Как под Oracle 10g переписать запрос?
И select listagg(str,',') within group(order by 1) vals, тоже в 10g не работает.
Достаточно просто:
select
regexp_substr(:s,'[^,]+',1,level)
from dual
connect by level<=length(:s)-length(translate(:s,'.,','.'))+1
А вместо listagg можно использовать, например, xmlagg, недокументированный wm_concat или собственные функции как кайтовский stragg.
Отправить комментарий