Я создал индекс Oracle Text следующим образом:
create index my_idx on my_table (text) indextype is ctxsys.context;
И тогда я могу сделать следующее:
select * from my_table where contains(text, '%blah%') > 0;
Но допустим, у нас есть другой столбец в этой таблице, скажем, group_id
, и вместо этого я хотел выполнить следующий запрос:
select * from my_table where contains(text, '%blah%') > 0 and group_id = 43;
С указанным выше индексом Oracle должен будет искать все элементы, содержащие 'blah'
, а затем проверять все их group_id
.
В идеале я бы предпочел искать только элементы с group_id = 43
, поэтому мне нужен такой индекс:
create index my_idx on my_table (group_id, text) indextype is ctxsys.context;
Похоже на обычный индекс, поэтому для каждого group_id
можно выполнять отдельный текстовый поиск.
Есть ли способ сделать что-то подобное в Oracle (я использую 10g, если это важно)?
Изменить (пояснение)
Рассмотрим таблицу с миллионом строк и следующими двумя столбцами, среди прочих, A
и B
, оба числовые. Допустим, существует 500 различных значений A
и 2000 различных значений B
, и каждая строка уникальна.
Теперь давайте рассмотрим select ... where A = x and B = y
Насколько я могу судить, индекс по A
и B
отдельно выполняет поиск по индексу по B
, который возвращает 500 разных строк, а затем выполняет объединение/сканирование этих строк. В любом случае необходимо просмотреть не менее 500 строк (кроме того, что базе данных повезет и она найдет нужную строку раньше.
В то время как индекс по (A,B)
намного эффективнее, он находит одну строку за один поиск по индексу.
Помещение отдельных индексов на group_id
и текст, который я чувствую, оставляет генератору запросов только два варианта.
(1) Используйте индекс group_id
и просмотрите все результирующие строки в поисках текста.
(2) Используйте текстовый индекс и просмотрите все результирующие строки в поисках group_id
.
(3) Используйте оба индекса и сделать присоединение.
В то время как я хочу:
(4) Используйте индекс (group_id, "text")
, чтобы найти текстовый индекс под конкретным group_id
и отсканировать этот текстовый индекс для конкретной строки/строк, которые мне нужны. Не требуется сканирование, проверка или объединение, как при использовании индекса на (A,B)
.
contains(text, ...)
.contains()
— это не функция, которую вы используете для фильтрации результатов на основе появления определенного слова. На самом деле он вычисляет своего рода оценку релевантности любого данного текста для столбца, в котором вы его используете. - person NullUserException   schedule 14.09.2011text = 'hello world'
. Когда вы делаетеwhere contains(text, 'hello') > 0
, эта строка может быть включена или нет. Вы уверены, что это именно то, чего вы на самом деле хотите? - person NullUserException   schedule 14.09.2011contains(...)
(иcatsearch(...)
), и выполняет ли кто-либо из них полнотекстовый поиск? (то есть то, что вы обычно получаете, если используете find в текстовом редакторе). - person Clinton   schedule 14.09.2011