【问题标题】:Optimization of text parsing - Oracle SQL文本解析的优化——Oracle SQL
【发布时间】:2019-07-24 12:02:06
【问题描述】:

我正在处理一个 SQL 查询,该查询将计算某些单词在“长文本”或 CLOB 数据类型的巨大文本字段中出现的次数。

我的数据集(很大,大约 5M+ 行)看起来像这样:

http://sqlfiddle.com/#!4/2c13d/1

我有一个查询,如下所示:

SELECT
  TheTask AS Tasking,
  SUM(CASE WHEN TRIM(UPPER(TheTaskText)) LIKE '%LONG%' THEN 1 ELSE 0 END) AS LongCount,
  SUM(CASE WHEN TRIM(UPPER(TheTaskText)) LIKE '%TEXT%' THEN 1 ELSE 0 END) AS TextCount,
  SUM(CASE WHEN TRIM(UPPER(TheTaskText)) LIKE '%ENGLISH%' THEN 1 ELSE 0 END) AS EnglishCount
FROM
  example
GROUP BY
  TheTask

但是,在完整的数据集上运行需要很长时间(约 3 小时左右)。我相信这是由于LIKE optimization issues,但我不确定如何实现这个目标数据集。我曾尝试在how to optimize like 上研究其他文章,但REGEX 是否可能会更快?我希望通过评估 LIKE 的性能来优化此查询。

【问题讨论】:

  • 我不知道那是什么。
  • `LIKE '%sth' 不是 SARGable,因此性能很差。如果您真的需要搜索文本,那么 FTI 就是您所需要的。
  • 每次运行查询时单词是否不同?如果没有,您可以在插入一行时计算它们(使用 tirgger,f.e.)并使用单独的列来存储值。
  • 问题是我正在处理历史数据集,我无法控制对数据库应用程序@PavelSmirnov 的任何“W”权限

标签: sql oracle oracle11g sql-like


【解决方案1】:

CONTEXT 索引类型用于索引长文本。您可以使用:

CREATE INDEX idx_TheTaskTxt ON example(TRIM(UPPER(TheTaskText))) INDEXTYPE IS CTXSYS.CONTEXT;

并收集统计信息以使优化器生效:

EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'EXAMPLE', cascade=>TRUE);

并调用

SELECT
  TheTask AS Tasking,
  SUM(CASE WHEN CONTAINS(TRIM(UPPER(TheTaskText)), 'LONG', 1) > 0 THEN 1 ELSE 0 END) AS LongCount,
  SUM(CASE WHEN CONTAINS(TRIM(UPPER(TheTaskText)), 'TEXT', 1) > 0 THEN 1 ELSE 0 END) AS TextCount,
  SUM(CASE WHEN CONTAINS(TRIM(UPPER(TheTaskText)), 'ENGLISH', 1) > 0 THEN 1 ELSE 0 END) AS EnglishCount
FROM example
GROUP BY TheTask
HAVING 
       SUM(CASE WHEN CONTAINS(TRIM(UPPER(TheTaskText)), 'LONG', 1) > 0 THEN 1 ELSE 0 END) * 
       SUM(CASE WHEN CONTAINS(TRIM(UPPER(TheTaskText)), 'TEXT', 1) > 0 THEN 1 ELSE 0 END) *
       SUM(CASE WHEN CONTAINS(TRIM(UPPER(TheTaskText)), 'ENGLISH', 1) > 0 THEN 1 ELSE 0 END) 
       IN (0,1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-29
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    相关资源
    最近更新 更多