Подсчет попаданий со структурированным предикатом, содержащим LIKE в Oracle, возвращает неверные результаты

Я пытаюсь использовать Oracle Text для выполнения запроса, в котором я ищу любое имя ОС, которое начинается с «AIX», а также содержит подстроку «XYZ». Каким-то образом эта формулировка запроса приводит к 0 результатам, хотя если я разобью его на отдельные части, результаты будут очевидными:

SELECT 
  COUNT(*) AS cnt
FROM 
  package_master 
WHERE 
  CONTAINS(doc,'%XYZ%',1)>0 AND UPPER(os) LIKE 'AIX%'

Это возвращает 0 результатов.

Но любопытно, если я изменю его на:

SELECT 
  COUNT(*) AS cnt
FROM 
  package_master 
WHERE 
  CONTAINS(doc,'%XYZ%',1)>0 AND UPPER(os)='AIX 6.1.0.0'

он возвращает результаты, но, конечно, только те, которые относятся к AIX 6.1.0.0...

Я использую Oracle 11g2.

Возможно ли, что в пакете ORACLE TEXT есть ошибка?

Думаю, я могу разбить два запроса INTERSECT и выполнить COUNT(*) результатов, но это усложняет дело и, кажется, выполняется долго... Я хотел бы использовать простую форму "И".... Если возможно...

Это работает, но работает долго и излишне сложно:

SELECT count(*) FROM (
SELECT 
  host, package_name
FROM 
  package_master 
WHERE 
  CONTAINS(doc,'%XYZ%',1)>0
INTERSECT 
SELECT 
  host, package_name
FROM 
  package_master 
WHERE 
  UPPER(os) LIKE 'AIX%'
)

Также обратите внимание, что если я попытаюсь выполнить EXPLAIN для исходного запроса, это как если бы часть запроса «LIKE» вообще не выполнялась...! Это довольно странно:

Plan hash value: 1075233541


    ----------------------------------------------------------------------------------------
    | Id  | Operation        | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT |                     |     1 |   238 |    55   (0)| 00:00:01 |
    |   1 |  SORT AGGREGATE  |                     |     1 |   238 |            |          |
    |*  2 |   DOMAIN INDEX   | PACKAGE_MASTER_IDX7 |   100 | 23800 |    55   (0)| 00:00:01 |
    ---------------------------------------------------------------------------------------

    -


    Predicate Information (identified by operation id):
    ---------------------------------------------------

       2 - access("CTXSYS"."CONTAINS"("DOC",'%XYZ%',1)>0)
           filter(UPPER("OS") LIKE 'AIX%')

Oracle Database 11g Enterprise Edition, выпуск 11.2.0.3.0 — 64-разрядная версия. Значение NLS_COMP — BINARY, значение NLS_SORT — null. Таблица загружается только один раз, поэтому с синхронизацией индекса проблем не возникает.


person user3892260    schedule 26.10.2014    source источник


Ответы (2)


Как ни странно, я больше не вижу эту проблему! Я не могу воспроизвести поведение результата 0, и теперь, если я выполняю план EXPLAIN, я вижу, что оптимизатор работает правильно. Не так много изменилось. Возможно, Oracle просто потребовался перезапуск... Думаю, я закрою этот вопрос, хотя не было удовлетворительной причины/объяснения того, как проблема разрешилась сама собой.

person user3892260    schedule 10.11.2014

Собственно проблема вернулась...

Мои счетчики снова показывают неверные значения...

Оптимизатор оракула в очередной раз решил проигнорировать одно из условий предложения WHERE. Я запустил EXPLAIN PLAN и убедился, что он игнорирует половину предложения where, что мне кажется ошибкой.

Я решил переписать все запросы так, чтобы часть CONTAINS() находилась в одной области, а остальная часть фильтрации выполнялась в другом месте.

Кажется, держится.

Новый формат запроса, который я выбрал, кажется, работает:

WITH x AS (
  SELECT 
   * 
  FROM 
   package_master_naught 
  WHERE 
   CONTAINS(p_n_c,'%XYZ%',1)>0
) 
SELECT 
  COUNT(*) AS cnt
FROM 
  x 
WHERE 
  UPPER(os) LIKE 'AIX%';
person user3892260    schedule 13.11.2014