【问题标题】:Counting Hits with a Structured Predicate containing LIKE in Oracle returns wrong results在 Oracle 中使用包含 LIKE 的结构化谓词计算命中返回错误结果
【发布时间】:2014-10-26 18:36:33
【问题描述】:

我正在尝试使用 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 数据库 11g 企业版版本 11.2.0.3.0 - 64 位。 NLS_COMP 值为 BINARY,NLS_SORT 值为空。该表只加载一次,因此同步索引不是问题。

【问题讨论】:

  • 需要注意的是,如果我将 COUNT(*) 替换为列列表,查询会正确运行并返回正确的行数...
  • 换句话说:SELECT host, package_name FROM package_master WHERE CONTAINS(doc,'%XYZ%',1)>0 AND UPPER(os) LIKE 'AIX%' 返回预期的 770 行。 ..
  • 是的,该帖子没有解决这个问题...
  • 您正在运行什么确切 Oracle 版本?

标签: oracle text oracle-text


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    其实问题又来了……

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多