2

我正在尝试使用 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(*),但这会使事情复杂化并且似乎运行了很长时间......我想使用简单的“AND”形式......如果可能的话...

这有效但运行了很长时间并且不必要地复杂:

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 企业版 11.2.0.3.0 - 64 位。NLS_COMP 值为 BINARY,NLS_SORT 值为空。该表仅加载一次,因此同步索引不是问题。

4

2 回答 2

1

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

于 2014-11-10T18:46:08.753 回答
0

其实问题又来了……

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

oracle 优化器再次决定忽略 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%';
于 2014-11-13T20:31:10.227 回答