Regular expression vs oracle text performance

Does anyone have experience with comparig performance of regular expression vs oracle text?
We need to implement a text search on a large volume table, 100K-500K rows.
The select stmt will select from a VL, a view joining 2 tables, B and _TL.
We need to search 2 text columns from this _VL view.
Using regex seems less complex, but the deciding factor is of course performace.
Would oracle text search perform better than regular expression in general?
Thanks,
Margaret

Hi Dominc,
Thanks, we'll try both...
Would you be able to validate our code to create the multi-table index:
CREATE OR REPLACE PACKAGE requirements_util AS
PROCEDURE concat_columns(i_rowid IN ROWID, io_text IN OUT NOCOPY VARCHAR2);
END requirements_util;
CREATE OR REPLACE PACKAGE BODY requirements_util AS
PROCEDURE concat_columns(i_rowid IN ROWID, io_text IN OUT NOCOPY VARCHAR2)
AS
tl_req pjt_requirements_tl%ROWTYPE;
b_req pjt_requirements_b%ROWTYPE;
CURSOR cur_req_name (i_rqmt_id IN pjt_requirements_tl.rqmt_id%TYPE) IS
SELECT rqmt_name FROM pjt_requirements_tl
WHERE rqmt_id = i_rqmt_id;
PROCEDURE add_piece(i_add_str IN VARCHAR2) IS
lx_too_big EXCEPTION;
PRAGMA EXCEPTION_INIT(lx_too_big, -6502);
BEGIN
io_text := io_text||' '||i_add_str;
EXCEPTION WHEN lx_too_big THEN NULL; -- silently don't add the string.
END add_piece;
BEGIN
     BEGIN
          SELECT * INTO b_req FROM pjt_requirements_b WHERE ROWID = i_rowid;
          EXCEPTION
          WHEN NO DATA_FOUND THEN
          RETURN;
     END;
     add_piece(b_req.req_code);
     FOR tl_req IN cur_req_name(b_req.rqmt_id) LOOP
     add_piece(tl_req.rqmt_name);
END concat_columns;
END requirements_util;
EXEC ctx_ddl.drop_section_group('rqmt_sectioner');
EXEC ctx_ddl.drop_preference('rqmt_user_ds');
BEGIN
ctx_ddl.create_preference('rqmt_user_ds', 'USER_DATASTORE');
ctx_ddl.set_attribute('rqmt_user_ds', 'procedure', sys_context('userenv','current_schema')||'.'||'requirements_util.concat_columns');
ctx_ddl.set_attribute('rqmt_user_ds', 'output_type', 'VARCHAR2');
END;
CREATE INDEX rqmt_cidx ON pjt_requirements_b(req_code)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('DATASTORE rqmt_user_ds
SYNC (ON COMMIT)');

Similar Messages

  • Regular Expressions in Oracle

    Hello All,
    I come from Perl scripting language background. Perl's regular expressions are rock solid, robust and very fast.
    Now I am planning to master Regular Expressions in Oracle.
    Could someone please point the correct place to start with it like official Oracle documentation on Regular Expressions, any good book on Regex or may be any online link etc.
    Cheers,
    Parag
    Edited by: Parag Kalra on Dec 19, 2009 11:03 AM

    Hi, Parag,
    Look under [R in the index of the SQL language manual|http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/index.htm#R]. All the regular expression functions and operators start with "REGEXP", and there are a couple of entries under "regular expressions".
    That applies to the Oracle 11 and 10.2 documentation. Regular expressions were hidden in the Oracle 10.1 SQL Language manual; you had to look up some similar function (like REGR_SYY, itself hidden under S for "SQL Functions", and then step through the pages one at a time.
    Sorry, I don't know a good tutorial or introduction.
    If you find something hopeful, please post a reference here. I think a lot of people would be interrested.

  • Regular expressions in oracle 10 g

    how to use regular expressions in oracle 10g forms

    May be forms related question better answered in forms forum.
    Forms

  • Grouping & Back-references with regular expressions on Replace Text window

    I really appreciate the inclusion of the Regular Expressions in the search & replace feature. One thing I am missing is back-references in the replacement expression. For instance, in the unix tools vi or sed, I might do something like this:
    s/\(firstPart\) \(secondPart\) \(oldThirdPart\)/\2 \1 newThirdPart/g
    which would allow me to switch the places of firstPart and secondPart, and totally replace thirdPart. If grouping and back-references are already present in the Replace Text window, how does one correctly invoke them?

    duplicate of Grouping & Back-references with regular expressions on Replace Text window

  • Need a regular expression for the text field

    Hi ,
    I need a regular expression for a text filed.
    if the value is alphanumeric then min 3 char shud be there
    and if the value is numeric then no limit of chars in that field.[0-9].
    Any help is appriciated...
    thanks
    bharathi.

    Try the following in the change event:
    r=/^[a-z]{1,3}$|^\d+$/i;
    if (!r.test(xfa.event.newText))
    xfa.event.change="";
    Kyle

  • Regular Expressions and Full-text Requests.

    Hi,
    i have just read that Berkeley DB XML doesnt support regexp in XQuery (what a pity),
    do you know how to look-alike regular expressions in Query?
    for example, i'd like to perform a full-text request, all tags that contains text like "Be.+ley" (it would return tags that contains text like "Berkeley" or "Beverley"), how can i do that?
    Thx.

    Hi,
    A performant way to do something like you want is with a query that mixes use of contains() (index optimized) and matches() (not index optimized). Something like this:
    collection()//tag[contains(., "Be") and contains(., "ley") and matches(., "Be.+ley")]John

  • Oracle text performance with context search indexes

    Search performance using context index.
    We are intending to move our search engine to a new one based on Oracle Text, but we are meeting some
    bad performance issues when using search.
    Our application allows the user to search stored documents by name, object identifier and annotations(formerly set on objects).
    For example, suppose I want to find a document named ImportSax2.c: according to user set parameters, our search engine format the following
    search queries :
    1) If the user explicitely ask for a search by document name, the query is the following one =>
         select objid FROM ADSOBJ WHERE CONTAINS( OBJFIELDURL , 'ImportSax2.c WITHIN objname' , 1 ) > 0;
    2) If the user don't specify any extra parameters, the query is the following one =>
         select objid FROM ADSOBJ WHERE CONTAINS( OBJFIELDURL , 'ImportSax2.c' , 1 ) > 0;
    Oracle text only need around 7 seconds to answer the second query, whereas it need around 50 seconds to give an answer for the first query.
    Here is a part of the sql script used for creating the Oracle Text index on the column OBJFIELDURL
    (this column stores a path to an xml file containing properties that have to be indexed for each object) :
    begin
    Ctx_Ddl.Create_Preference('wildcard_pref', 'BASIC_WORDLIST');
    ctx_ddl.set_attribute('wildcard_pref', 'wildcard_maxterms', 200) ;
    ctx_ddl.set_attribute('wildcard_pref','prefix_min_length',3);
    ctx_ddl.set_attribute('wildcard_pref','prefix_max_length',6);
    ctx_ddl.set_attribute('wildcard_pref','STEMMER','AUTO');
    ctx_ddl.set_attribute('wildcard_pref','fuzzy_match','AUTO');
    ctx_ddl.set_attribute('wildcard_pref','prefix_index','TRUE');
    ctx_ddl.set_attribute('wildcard_pref','substring_index','TRUE');
    end;
    begin
    ctx_ddl.create_preference('doc_lexer_perigee', 'BASIC_LEXER');
    ctx_ddl.set_attribute('doc_lexer_perigee', 'printjoins', '_-');
    ctx_ddl.set_attribute('doc_lexer_perigee', 'BASE_LETTER', 'YES');
    ctx_ddl.set_attribute('doc_lexer_perigee','index_themes','yes');
    ctx_ddl.create_preference('english_lexer','basic_lexer');
    ctx_ddl.set_attribute('english_lexer','index_themes','yes');
    ctx_ddl.set_attribute('english_lexer','theme_language','english');
    ctx_ddl.set_attribute('english_lexer', 'printjoins', '_-');
    ctx_ddl.set_attribute('english_lexer', 'BASE_LETTER', 'YES');
    ctx_ddl.create_preference('german_lexer','basic_lexer');
    ctx_ddl.set_attribute('german_lexer','composite','german');
    ctx_ddl.set_attribute('german_lexer','alternate_spelling','GERMAN');
    ctx_ddl.set_attribute('german_lexer','printjoins', '_-');
    ctx_ddl.set_attribute('german_lexer', 'BASE_LETTER', 'YES');
    ctx_ddl.set_attribute('german_lexer','NEW_GERMAN_SPELLING','YES');
    ctx_ddl.set_attribute('german_lexer','OVERRIDE_BASE_LETTER','TRUE');
    ctx_ddl.create_preference('japanese_lexer','JAPANESE_LEXER');
    ctx_ddl.create_preference('global_lexer', 'multi_lexer');
    ctx_ddl.add_sub_lexer('global_lexer','default','doc_lexer_perigee');
    ctx_ddl.add_sub_lexer('global_lexer','german','german_lexer','ger');
    ctx_ddl.add_sub_lexer('global_lexer','japanese','japanese_lexer','jpn');
    ctx_ddl.add_sub_lexer('global_lexer','english','english_lexer','en');
    end;
    begin
         ctx_ddl.create_section_group('axmlgroup', 'AUTO_SECTION_GROUP');
    end;
    drop index ADSOBJ_XOBJFIELDURL force;
    create index ADSOBJ_XOBJFIELDURL on ADSOBJ(OBJFIELDURL) indextype is ctxsys.context
    parameters
    ('datastore ctxsys.file_datastore
    filter ctxsys.inso_filter
    sync (on commit)
    lexer global_lexer
    language column OBJFIELDURLLANG
    charset column OBJFIELDURLCHARSET
    format column OBJFIELDURLFORMAT
    section group axmlgroup
    Wordlist wildcard_pref
    Oracle created a table named DR$ADSOBJ_XOBJFIELDURL$I which now contains around 25 millions records.
    ADSOBJ is the table contaings information for our documents,OBJFIELDURL is the field that contains the path to the xml file containing
    data to index. That file looks like this :
    <?xml version="1.0" encoding="UTF-8" ?>
    <fields>
    <OBJNAME><![CDATA[NomLnk_177527o.jpgp]]></OBJNAME>
    <OBJREM><![CDATA[Z_CARACT_141]]></OBJREM>
    <OBJID>295926o.jpgp</OBJID>
    </fields>
    Can someone tell me how I can make that kind of request
    "select objid FROM ADSOBJ WHERE CONTAINS( OBJFIELDURL , 'ImportSax2.c WITHIN objname' , 1 ) > 0;"
    run faster ?

    Below are the execution plan for both the 2 requests :
    select objid FROM ADSOBJ WHERE CONTAINS( OBJFIELDURL , 'ImportSax2.c WITHIN objname' , 1 ) > 0
    PLAN_TABLE_OUTPUT
    |     Id     | Operation                              |Name                         |Rows     |Bytes     |Cost (%CPU)|
    |     0     | SELECT STATEMENT                    |                              |1272     |119K     |     4     (0)     |
    |     1      | TABLE ACCESS BY INDEX ROWID     |ADSOBJ      |1272     |119K     |     4     (0)     |
    |     2      |     DOMAIN INDEX                    |ADSOBJ_XOBJFIELDURL     |          |          |     4     (0)     |
    Note
    - 'PLAN_TABLE' is old version
    Executed in 2 seconds
    select objid FROM ADSOBJ WHERE CONTAINS( OBJFIELDURL , 'ImportSax2.c' , 1 ) > 0
    PLAN_TABLE_OUTPUT
    |     Id     |Operation                              |Name                         |Rows     |Bytes     |Cost (%CPU)|
    |     0     | SELECT STATEMENT                    |                              |1272     |119K     |     4     (0)     |
    |     1     | TABLE ACCESS BY INDEX ROWID     |ADSOBJ                         |1272     |119K     |     4     (0)     |
    |     2     | DOMAIN INDEX                    |ADSOBJ_XOBJFIELDURL     |          |          |     4     (0)     |
    Sorry for the result formatting, I can't get it "easily" readable :(

  • Regular expressions in Oracle 9i

    Hello,
    Does oracle 9i support regular expressions?
    I need to check if a varchar parameter contains only numbers OR letters, otherwise i should return false.
    Thanks.

    Roger22 wrote:
    Hello,
    Does oracle 9i support regular expressions?
    I need to check if a varchar parameter contains only numbers OR letters, otherwise i should return false.
    Thanks.TRANSLATE is helpful to do such a check.
    example
    WITH testdata AS
       (SELECT 'abcdef' txt FROM DUAL UNION ALL
        SELECT '1234567' txt FROM DUAL union all
        SELECT '0' txt FROM DUAL union all
        SELECT '123a4567x00' txt FROM DUAL union all
        SELECT '123.4567,00' txt FROM DUAL
    select txt,
           translate(txt,'a1234567890','a')  numbers_removed,
           translate(txt,'0abcdefghijklonopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ','0')  letters_removed
    from testdata;
    TXT            NUMBERS_REMOVED     LETTERS_REMOVED
    abcdef           abcdef     
    1234567             1234567
    0                        0
    123a4567x00     ax     123456700
    123.4567,00     .,     123.4567,00One idea is to check the result for NULL or to compare the length of similiar expressions.
    Problems are usually special chars and how you want to handle that.
    Edited by: Sven W. on Aug 11, 2010 11:07 AM
    Edited by: Sven W. on Aug 11, 2010 11:07 AM

  • Regular expression in oracle for hypen

    Hi,
    I want to match a word "{color:#993300}83-ASG{color}" using regexp_like and i used '{color:#993300}^83-*{color}' pattern to match this word but this also matches words like "{color:#993300}8307-YUF{color}". could anyone please tell me what pattern should i use to match words like {color:#993300}83-ASG{color}.
    Also i need to know the similar pattern in oracle for the "{color:#993300}\b{}{color}" used in .net.
    Thanks in advance.
    Prasad

    Hi Prasad,
    Your regex could be as simple as '^83-'
    So, not much use for a regular expression:
    SQL> with test_data as (select '83-ASG' txt from dual union all
                       select '8307-YUF' from dual)
    -- end of test data
    select txt from test_data
    where txt like '83-%'
    TXT    
    83-ASG 
    1 row selected.Unless, you add some more value to it, perhaps like
    SQL> with test_data as (select '83-ASG' txt from dual union all
                       select '8307-YUF' from dual)
    -- end of test data
    select txt from test_data
    where regexp_like(txt, '^83-[[:upper:]]{3}$')
    TXT    
    83-ASG 
    1 row selected.Regards
    Peter

  • Regular expressions for replacing text with sms language text

    Hi, I'm trying to write a function which converts normal, correctly spelled text into the shorter sms language format but struggling to come up with the regular expressions i need to do so, can anyone help?
    1: remove surplus white space at the beginning of a sentence and at the end of a sentence.
    e.g. " hello." --> "hello." OR "hello ." --> "hello."
    2: remove preceeding and/or proceeding space if there's a word then a number possibly followed by another word
    e.g. "come 2 me" --> "come2me" OR "dnt 4get" --> "dnt4get"
    3: remove "aeiou" if word starts and ends with "!aeiou"
    e.g. "text" --> "txt"

    You can make the whitespace on either side optional:   text = text.replaceAll("\\s*(\\d)\\s*", "$1");1. Use String's trim() method.
    3. This one has to be done in two steps: import java.util.regex.*;
    public class Test
      public static void main(String... args) throws Exception
        String text = "The quick brown fox jumps over the lazy dog.";
        System.out.println(devowelize(text));
      public static String devowelize(String str)
        Pattern p = Pattern.compile(
          "[a-z&&[^aeiou]]++(?:[aeiou]++[a-z&&[^aeiou]]++)+",
          Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (m.find())
          m.appendReplacement(sb, m.group().replaceAll("[aeiou]+", ""));
        m.appendTail(sb);
        return sb.toString();
    }

  • Esing regular expression to reformat text (match & replace)

    Hi guys ..I am using regilar expression to reformat logs files..
    this is how i match the pattern..
    Pattern pattern = Pattern.compile("^<[^>]*>(.{6}).....
    Matcher matcher = pattern.matcher(thisLine);
    then prints the output...
    myOutput.print(matcher.group(1));
    It works..however my prob now is, i am reading a date in format "8 Nov"
    How can i change this to 8-11-2005 ????

    hmmm....ya..i can see the idea
    (\\d\\d?) (Jan|Feb|Mar|Apr|May|Ju[nl]|Aug|Sep|Oct|Nov|Dec) means that the month can be either one rite?
    but the thing is..its collected and put in a group. for example:
    Pattern pattern = Pattern.compile("^<[^>]*>(.{6}) ...
    myOutput.print(matcher.group(1));
    the first regular expression is group in group(1). its working..it can detect the text in group(1) the problem was...i tried this..
    String priority = matcher.group(6);
                   if (priority=="3")
                        System.out.print("AAA\n");
                   else
                   System.out.print("BBB\n");
    it keeps on printing BBB even there is a "priority=3".

  • Regular Expression/Replace - Oracle 7.3

    Hi!
    I am trying the regular expression SQL functions of 10g to Oracle 7.3 and it seems the older version does not cover this feature yet.
    "Aaaa,Bbbb" --> "Aaaa, Bbbb"
    REPLACE *",[0-9A-Za-z]"* WITH *", "*
    The string pattern is to look for comma-punctuations that is not followed immediately by whitespacess so I can replace this with a comma followed by a whitespace.
    Any workaround for this?

    Hi,
    Welcome to the forum!
    kitsune wrote:
    Hi!
    I am trying the regular expression SQL functions of 10g to Oracle 7.3 and it seems the older version does not cover this feature yet.You're right; regular expressions only work in Oracle 10.1 and higher.
    >
    >
    "Aaaa,Bbbb" --> "Aaaa, Bbbb"
    REPLACE *",[0-9A-Za-z]"* WITH *", "*
    The string pattern is to look for comma-punctuations that is not followed immediately by whitespacess so I can replace this with a comma followed by a whitespace.
    Any workaround for this?You're best bet in Oracle 7.3 would be a user-defined function. That's a very old version; don't expect much.
    Do you know anything else about the string? For example, is there some character (say ~) that never occurs in the string? Will there ever be two (or more) whitespace characters after punctuation? What characters do you consider to be whitespace? Which are punctuation? Depending on the answers, you might be able to do something with nested REPLACE and/or TRANSLATE functions.

  • Need regular expression for oracle date format 'DD-MON-YYYY'

    Hi,
    Can anybody tell me the regular expression to validate date in 'DD-MON-YYYY'.
    My concept is i have a table with just two columns item_name and item_date
    Both fields are varchar2 and i want to fetch those records from this table which have valid date format('DD-MON-YYYY').

    If it must be a regexp, this is a starter for you, note it carries the caveats mentioned by both posters above and in the linked thread
    mkr02@ORA11GMK> with data as (select '10-jan-2012' dt from dual
      2  union all select '10-111-2012' from dual
      3  union all select 'mm-jan-2012' from dual
      4  union all select '10-jan-12' from dual)
      5  select
      6  dt,
      7  case when regexp_like(dt,'[[:digit:]]{2}-[[:alpha:]]{3}-[[:digit:]]{4}','i') then 1 else 0 end chk
      8  from data
      9  /
    DT                 CHK
    10-jan-2012          1
    10-111-2012          0
    mm-jan-2012          0
    10-jan-12            0It will not validate content, only string format.
    And to emphasis the points made in the linked thread - dates in text columns is poor design. Always.

  • Oracle Text performance -- failed attempts

    We are trying to implement a simple search of text data stored in a heavily used table (inserts/updates). There are 3 columns to index --
    Headline (varchar2(255))
    Subheadline (varchar2(255))
    Teaser (varchar2(4000))
    The first attempt to implement Oracle text w/ CATSEARCH
    begin
    ctx_ddl.create_index_set('cms_iset');
    ctx_ddl.add_index('cms_iset','poolid_cp, mediaid_cp'); /* sub-index A */
    end;
    ---- We knew we were going to filter on poolid_cp and mediaid_cp ---
    CREATE INDEX cms_headlineidx ON con_properties (headline)
    INDEXTYPE IS ctxsys.CTXCAT
    PARAMETERS ('index set cms_iset');
    CREATE INDEX cms_subheadlineidx ON con_properties (subheadline)
    INDEXTYPE IS ctxsys.CTXCAT
    PARAMETERS ('index set cms_iset');
    CREATE INDEX cms_teaseridx ON con_properties (teaser)
    INDEXTYPE IS ctxsys.CTXCAT
    PARAMETERS ('index set cms_iset');
    *********THE RESULTS*************
    Our application server would spin up threads that would appear to be hanging. The load on the DB servers (RAC) were higher than normal. This implementation would have saved on having to do resync's manually.
    The next attempt was implementing w/ CONTEXT:
    alter table con_properties add (dummy varchar2(1));
    begin
    ctx_ddl.create_preference('con_propsearch', 'MULTI_COLUMN_DATASTORE');
    ctx_ddl.set_attribute('con_propsearch', 'columns', 'headline,subheadline,teaser');
    end;
    CREATE INDEX con_properties_searchidx
    ON con_properties(dummy)
    INDEXTYPE IS CTXSYS.CONTEXT
    PARAMETERS ('datastore CTXSYS.con_propsearch')
    Records getting put into the ctx_user_pending table a few hundred per hour.
    ********THE RESULTS*************
    Same issue with the application servers spinning off threads that seem to be hung. Spikey load on the DB servers (RAC).
    NOTE: In both implementations, running search querys ran OK. However, dropping the text index in BOTH cases caused the application servers to behave normally.
    Can anyone tell me what's going on internally with Oracle TEXT when a table is heavily inserted and updated? What is going on in the background. Is there some sort of lock that the app servers are waiting on? I know there is "overhead" with inserts on a normal b-tree index. Is it "exponential" with Oracle Text?
    Thank you!

    When documents in the base table are inserted, updated, or deleted, their ROWIDs are held in a DML queue until you synchronize the index. You can view this queue with the CTX_USER_PENDING view. Apparently, you are not synchronizing your context index, so the queue is building infinitely. You need to establish some method of synchronizing your index. You can use parameters('sync(on commit)') in your index creation or create an after insert or update statement level trigger, not row trigger, that uses dbms_job.submit to schedule ctx_ddl.sync_index to synchronize the index upon commit of the dml or you can manually run ctx_ddl.sync_index periodically or schedule it or you can alter and rebuild your index periodically or you can drop and recreate it periodically. Which method you choose depends on how current the information that you query needs to be. If your data needs to be current up to the moment, the you should sync on commit. Otherwise it may be better to do it in periodic batches.

  • Oracle text performance

    hi all.
    i have useing orcle text for the indexing purposes ..
    the below query goes for an wildcard search and it performance is very poor ..
    /* Formatted on 2009/08/11 16:06 (Formatter Plus v4.8.5) */
    SELECT *
      FROM (SELECT z.*, ROWNUM r
              FROM (SELECT   *
                        FROM (SELECT *
                                FROM (SELECT score (1) score,
                                             SUBSTR (note, 1, 200) note, tmplt_id,
                                             appl_name, appl_use, appl_reference,
                                             appl_entity, effctv_start_date,
                                             effctv_end_date, eq_name, note_id,
                                             Bfcommon.getvaluebasedontemplate
                                                                 (tmplt_id,
                                                                  note_id
                                                                 ) VALUE,
                                             (SELECT em_name
                                                FROM ip_eq
                                               WHERE eq_name = a.eq_name) em_name,
                                             Bfcommon.is_edit_allowed_note1
                                                       (a.note_id,
                                                        'PACRIM1\E317329',
                                                        SYSDATE,
                                                        SYSDATE
                                                       ) LOCKED
                                        FROM bf_note a
                                       WHERE tmplt_id NOT IN (19, 14, 16)
                                         AND effctv_start_date >=
                                                TO_DATE ('08/12/2008 00:00:00',
                                                         'MM/DD/YYYY HH24:MI:SS'
                                         AND (   effctv_end_date <=
                                                    TO_DATE
                                                          ('08/12/2009 00:00:00',
                                                           'MM/DD/YYYY HH24:MI:SS'
                                              OR effctv_end_date IS NULL
                                         AND contains (note, '%test%', 1) > 0) r
                              UNION
                              SELECT score (1) score, SUBSTR (note, 1, 200) note,
                                     tmplt_id, appl_name, appl_use,
                                     appl_reference, appl_entity,
                                     effctv_start_date, effctv_end_date, eq_name,
                                     a.note_id, b.trgt_name VALUE,
                                     (SELECT em_name
                                        FROM ip_eq
                                       WHERE eq_name = a.eq_name) em_name,
                                     Bfcommon.is_edit_allowed_note1
                                                       (a.note_id,
                                                        'PACRIM1\E317329',
                                                        SYSDATE,
                                                        SYSDATE
                                                       ) LOCKED
                                FROM bf_note a, om_limit_hist b
                               WHERE (   date_changed =
                                            (SELECT MAX (date_changed)
                                               FROM om_limit_hist h1
                                              WHERE date_changed <
                                                       (SELECT MAX (date_changed)
                                                          FROM om_limit_hist h2
                                                         WHERE h2.trgt_name =
                                                                       b.trgt_name)
                                                AND h1.trgt_name = b.trgt_name)
                                      OR date_changed =
                                               (SELECT MAX (date_changed)
                                                  FROM om_limit_hist h1
                                                 WHERE h1.trgt_name = b.trgt_name)
                                 AND b.note_id = a.note_id(+)
                                 AND tmplt_id = 19
                                 AND effctv_start_date >=
                                        TO_DATE ('08/12/2008 00:00:00',
                                                 'MM/DD/YYYY HH24:MI:SS'
                                 AND (   effctv_end_date <=
                                            TO_DATE ('08/12/2009 00:00:00',
                                                     'MM/DD/YYYY HH24:MI:SS'
                                      OR effctv_end_date IS NULL
                                 AND contains (note, '%test%', 1) > 0)
                    ORDER BY 1 DESC) z
             WHERE ROWNUM <= 50)
    WHERE r >= 1here it goes for the wild card search for the string test ...Plz tell me how to index it in this case ..
    and its plan is
    Execution Plan
    Plan hash value: 3535478881
    | Id  | Operation                            | Name                | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT                     |                     |    50 |   128K|       |   632   (1)| 00:00:08 |
    |*  1 |  VIEW                                |                     |    50 |   128K|       |   632   (1)| 00:00:08 |
    |*  2 |   COUNT STOPKEY                      |                     |       |       |       |         |     |
    |   3 |    VIEW                              |                     |    69 |   177K|       |   632   (1)| 00:00:08 |
    |*  4 |     SORT ORDER BY STOPKEY            |                     |    69 |   177K|   376K|   632   (1)| 00:00:08 |
    |   5 |      VIEW                            |                     |    69 |   177K|       |   590   (1)| 00:00:08 |
    |   6 |       SORT UNIQUE                    |                     |    69 |  7281 |       |   590   (2)| 00:00:08 |
    |   7 |        UNION-ALL                     |                     |       |       |       |         |     |
    |*  8 |         TABLE ACCESS BY INDEX ROWID  | BF_NOTE             |    68 |  7140 |       |   585   (1)| 00:00:08 |
    |*  9 |          DOMAIN INDEX                | BF_NOTE_TEXT_SEARCH |       |       |       |   221   (0)| 00:00:03 |
    |* 10 |         FILTER                       |                     |       |       |       |         |     |
    |  11 |          NESTED LOOPS                |                     |     1 |   141 |       |     3   (0)| 00:00:01 |
    |  12 |           TABLE ACCESS FULL          | OM_LIMIT_HIST       |     1 |    36 |       |     2   (0)| 00:00:01 |
    |* 13 |           TABLE ACCESS BY INDEX ROWID| BF_NOTE             |     1 |   105 |       |     1   (0)| 00:00:01 |
    |* 14 |            INDEX UNIQUE SCAN         | BF_NOTE_PK          |     1 |       |       |     1   (0)| 00:00:01 |
    |  15 |          SORT AGGREGATE              |                     |     1 |    23 |       |         |     |
    |* 16 |           INDEX RANGE SCAN           | OM_LIMIT_HIST_IDX1  |     1 |    23 |       |     0   (0)| 00:00:01 |
    |  17 |            SORT AGGREGATE            |                     |     1 |    23 |       |         |     |
    |* 18 |             INDEX RANGE SCAN         | OM_LIMIT_HIST_IDX1  |     1 |    23 |       |     0   (0)| 00:00:01 |
    |  19 |            SORT AGGREGATE            |                     |     1 |    23 |       |         |     |
    |* 20 |             INDEX RANGE SCAN         | OM_LIMIT_HIST_IDX1  |     1 |    23 |       |     0   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       1 - filter("R">=1)
       2 - filter(ROWNUM<=50)
       4 - filter(ROWNUM<=50)
       8 - filter("EFFCTV_START_DATE">=TO_DATE(' 2008-08-12 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
                  "TMPLT_ID"19 AND "TMPLT_ID"14 AND "TMPLT_ID"16 AND ("EFFCTV_END_DATE" IS NULL OR
                  "EFFCTV_END_DATE"<=TO_DATE(' 2009-08-12 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
       9 - access("CTXSYS"."CONTAINS"("NOTE",'%test%',1)>0)
      10 - filter("DATE_CHANGED"= (SELECT /*+ */ MAX("DATE_CHANGED") FROM "OM_LIMIT_HIST" "H1" WHERE
                  "H1"."TRGT_NAME"=:B1 AND "DATE_CHANGED"< (SELECT /*+ */ MAX("DATE_CHANGED") FROM "OM_LIMIT_HIST" "H2" WHER
    E
                  "H2"."TRGT_NAME"=:B2)) OR "DATE_CHANGED"= (SELECT /*+ */ MAX("DATE_CHANGED") FROM "OM_LIMIT_HIST" "H1"
                  WHERE "H1"."TRGT_NAME"=:B3))
      13 - filter("TMPLT_ID"=19 AND "EFFCTV_START_DATE">=TO_DATE(' 2008-08-12 00:00:00', 'syyyy-mm-dd
                  hh24:mi:ss') AND "CTXSYS"."CONTAINS"("NOTE",'%test%',1)>0 AND ("EFFCTV_END_DATE" IS NULL OR
                  "EFFCTV_END_DATE"<=TO_DATE(' 2009-08-12 00:00:00', 'syyyy-mm-dd hh24:mi:ss')))
      14 - access("B"."NOTE_ID"="A"."NOTE_ID")
      16 - access("H1"."TRGT_NAME"=:B1 AND "DATE_CHANGED"< (SELECT /*+ */ MAX("DATE_CHANGED") FROM
                  "OM_LIMIT_HIST" "H2" WHERE "H2"."TRGT_NAME"=:B2))
           filter("DATE_CHANGED"< (SELECT /*+ */ MAX("DATE_CHANGED") FROM "OM_LIMIT_HIST" "H2" WHERE
                  "H2"."TRGT_NAME"=:B1))
      18 - access("H2"."TRGT_NAME"=:B1)
      20 - access("H1"."TRGT_NAME"=:B1)

    What version of Oracle are you using?
    Your sample query is a good example of the benefits and costs of 'mixed' queries, and the challenges of mixed query performance. Oracle 11g has some very helpful new features (search for SDATA) that can really improve performance. (Specifically, it looks like your query does some useful date-range bounding. You need to get that into the FT index).
    In the end, it's not going to be easy to look at your reasonably complex query, understand the data and relationships, and wave the magic wand to make the thing go fast.

Maybe you are looking for