Oracle: Full text search with condition

前端 未结 4 1974
栀梦
栀梦 2020-12-13 16:27

I\'ve created an Oracle Text index like the following:

create index my_idx on my_table (text) indextype is ctxsys.context; 

And I can then

4条回答
  •  既然无缘
    2020-12-13 16:41

    Short version: There's no need to do that. The query optimizer is smart enough to decide what's the best way to select your data. Just create a btree index on group_id, ie:

    CREATE INDEX my_group_idx ON my_table (group_id); 
    

    Long version: I created a script (testperf.sql) that inserts 136 rows of dummy data.

    DESC my_table;
    
    Name     Null     Type      
    -------- -------- --------- 
    ID       NOT NULL NUMBER(4) 
    GROUP_ID          NUMBER(4) 
    TEXT              CLOB      
    

    There is a btree index on group_id. To ensure the index will actually be used, run this as a dba user:

    EXEC DBMS_STATS.GATHER_TABLE_STATS('', 'MY_TABLE', cascade=>TRUE);
    

    Here's how many rows each group_id has and the corresponding percentage:

    GROUP_ID               COUNT                  PCT                    
    ---------------------- ---------------------- ---------------------- 
    1                      1                      1                      
    2                      2                      1                      
    3                      4                      3                      
    4                      8                      6                      
    5                      16                     12                     
    6                      32                     24                     
    7                      64                     47                     
    8                      9                      7         
    

    Note that the query optimizer will use an index only if it thinks it's a good idea - that is, you are retrieving up to a certain percentage of rows. So, if you ask it for a query plan on:

    SELECT * FROM my_table WHERE group_id = 1;
    SELECT * FROM my_table WHERE group_id = 7;
    

    You will see that for the first query, it will use the index, whereas for the second query, it will perform a full table scan, since there are too many rows for the index to be effective when group_id = 7.

    Now, consider a different condition - WHERE group_id = Y AND text LIKE '%blah%' (since I am not very familiar with ctxsys.context).

    SELECT * FROM my_table WHERE group_id = 1 AND text LIKE '%ipsum%';
    

    Looking at the query plan, you will see that it will use the index on group_id. Note that the order of your conditions is not important:

    SELECT * FROM my_table WHERE text LIKE '%ipsum%' AND group_id = 1;
    

    Generates the same query plan. And if you try to run the same query on group_id = 7, you will see that it goes back to the full table scan:

    SELECT * FROM my_table WHERE group_id = 7 AND text LIKE '%ipsum%';
    

    Note that stats are gathered automatically by Oracle every day (it's scheduled to run every night and on weekends), to continually improve the effectiveness of the query optimizer. In short, Oracle does its best to optimize the optimizer, so you don't have to.

提交回复
热议问题