在Oracle中使用包含LIKE的结构化谓词计算命中数会返回错误的结果

在Oracle中使用包含LIKE的结构化谓词计算命中数会返回错误的结果,oracle,text,oracle-text,Oracle,Text,Oracle Text,我正在尝试使用Oracle文本执行一个查询,其中我正在搜索任何以AIX开头并包含子字符串“XYZ”的操作系统名称。不知何故,这种查询公式会在0个结果中产生结果,即使我将其分解为单独的部分,也会有明显的结果: SELECT COUNT(*) AS cnt FROM package_master WHERE CONTAINS(doc,'%XYZ%',1)>0 AND UPPER(os) LIKE 'AIX%' 这将返回0个结果 但奇怪的是,如果我将其修改为: SELECT

我正在尝试使用Oracle文本执行一个查询,其中我正在搜索任何以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'
它返回结果,但当然只返回与AIX6.1.0.0相关的结果

我正在使用Oracle 11g2

ORACLE文本包中是否可能存在错误

我想我可以分成两个INTERSECT查询并计算*结果,但这会使问题复杂化,而且似乎会运行很长时间。。。我想用简单的“和”形式。。。。如果可能的话

这可以工作,但会运行很长时间,而且不必要地复杂:

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%'
)
还要注意,如果我试图对原始查询进行解释,就好像查询的类似部分根本没有执行过一样。。。!这相当奇怪:

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值为二进制,NLS_SORT值为空。表只加载了一次,所以同步索引不会有问题。

奇怪的是,我不再看到这个问题了!我无法重现0结果行为,现在如果执行解释计划,我会看到优化器工作正常。变化不大。也许Oracle只是需要重新启动。。。我想我会结束这个问题,即使没有令人满意的理由/解释来说明问题是如何解决的。

事实上,问题又回来了

我的计数再次显示不正确的值

oracle优化器再次决定忽略WHERE子句的一个条件。我运行了解释计划并确认它忽略了where子句的一半,这在我看来像个bug

我决定重写所有的查询,使包含部分位于一个区域,其余的过滤在单独的位置完成

它似乎挺得住

我选择的似乎有效的新查询格式是:

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%';

应该注意的是,如果我用列列表替换COUNT*,查询将正确运行并返回正确的行数…换句话说:从package_master中选择host、package_name,其中CONTAINSdoc、“%XYZ%”、1>0和类似“AIX%”的UPPERos返回预期的770行…您看到了吗?是的,这篇文章并没有解决这个问题……您运行的是什么Oracle版本?