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 do the following:
select * from my_table where contains(text, '%blah%') > 0;
But lets say we have a have another column in this table, say group_id
, and I wanted to do the following query instead:
select * from my_table where contains(text, '%blah%') > 0 and group_id = 43;
With the above index, Oracle will have to search for all items that contain 'blah'
, and then check all of their group_id
s.
Ideally, I'd prefer to only search the items with group_id = 43
, so I'd want an index like this:
create index my_idx on my_table (group_id, text) indextype is ctxsys.context;
Kind of like a normal index, so a separate text search can be done for each group_id
.
Is there a way to do something like this in Oracle (I'm using 10g if that is important)?
Edit (clarification)
Consider a table with one million rows and the following two columns among others, A
and B
, both numeric. Lets say there are 500 different values of A
and 2000 different values of B
, and each row is unique.
Now lets consider select ... where A = x and B = y
An index on A
and B
separately as far as I can tell do an index search on B
, which will return 500 different rows, and then do a join/scan on these rows. In any case, at least 500 rows have to be looked at (aside from the database being lucky and finding the required row early.
Whereas an index on (A,B)
is much more effective, it finds the one row in one index search.
Putting separate indexes on group_id
and the text I feel only leaves the query generator with two options.
(1) Use the group_id
index, and scan all the resulting rows for the text.
(2) Use the text index, and scan all the resulting rows for the group_id
.
(3) Use both indexes, and do a join.
Whereas I want:
(4) Use the (group_id, "text")
index to find the text index under the particular group_id
and scan that text index for the particular row/rows I need. No scanning and checking or joining required, much like when using an index on (A,B)
.
contains(text, ...)
actually does.contains()
is not the kind of function you use to filter results based on occurrences of a certain word. It actually calculates a sort of relevance score any given text has for the column you are using it on. – Adkinsontext = 'hello world'
. When you do awhere contains(text, 'hello') > 0
this row might or not might be included. Are you sure this is what you actually want? – Adkinsoncontains(...)
(andcatsearch(...)
) actually does, and if any of them does a full text search? (i.e. what you typical get if you use "find" in a text editor). – Signorelli