【问题标题】:Alternative to multiple concats in WHERE clause?替代 WHERE 子句中的多个连接?
【发布时间】:2017-06-23 12:33:03
【问题描述】:

我有一个像这样的巨大查询:

SELECT 'Tipification', COUNT(*) TOTAL, to_char(INITDATE,'YYYY-MM-DD')
FROM (
    SELECT (TYPE || ' \ ' || SUBTYPE || ' \ ' || PROBLEM ) Triplet, INITDATE 
    FROM TABLE 
    WHERE USER IS NOT null 
        AND (INITDATE >= TO_DATE('2016-12-01 00:00', 'YYYY-MM-DD HH24:MI:SS')) 
        AND (INITDATE <= TO_DATE('2016-12-31 23:59', 'YYYY-MM-DD HH24:MI:SS')) 

        AND ( (TYPE || ' \ ' || SUBTYPE || ' \ ' || PROBLEM) = 'aaa \ bbb \ ccc' 
            OR (TYPE || ' \ ' || SUBTYPE || ' \ ' || PROBLEM) = 'aaa \ bbb \ ddd' 
            OR (TYPE || ' \ ' || SUBTYPE || ' \ ' || PROBLEM) = 'xxx \ yyy \ zzz' 
            OR (TYPE || ' \ ' || SUBTYPE || ' \ ' || PROBLEM) = 'qqq \ www \ eee'
            ... etc ...
)
GROUP BY to_char(INITDATE,'YYYY-MM-DD')

这里有 300 多个字符串连接:(TYPE || ' \ ' || SUBTYPE || ' \ ' || PROBLEM) = '... \ ... \ ...'

在执行这个查询时,我得到了一些核心转储,因为数据库执行起来太昂贵了。

有没有其他方法可以在数据库内存不足的情况下执行这样的查询?

【问题讨论】:

  • 为什么不在内联视图或 CTE 中进行串联而不是重复呢?或者使用in 比较各个列而不是查看连接值? (从中得到内存错误似乎很奇怪,但大概您已经排除了其他原因,并且内存目标很小?)
  • and type in (list of types) or subtype in (list of subtypes) or problem in (list of problems) 合乎逻辑吗?
  • AND ( (TYPE || ' \ ' || SUBTYPE || ' \ ' || PROBLEM) IN ('aaa \ bbb \ ccc', 'aaa \ bbb \ ddd' , 'xxx \ yyy \ zzz', 'qqq \ www \ eee') ?
  • 在我看来 TYPE/SUBTYPE/PROBLEM 是缺少的实体/表。我会重新评估设计

标签: sql oracle concatenation sqlperformance


【解决方案1】:

SAP HANA DB 替代连接查询:

select * from table_name
  WHERE (col_name1,col_name2,col_name3)
  IN (('value1','value2','value3'),.....);

同样,也可以在更新和删除查询中使用它。

【讨论】:

    【解决方案2】:

    Oracle 有一个不错的 in 函数,允许您放入多个列组合。

    select to_char(INITDATE,'YYYY-MM-DD'), count(*)
    from table
    where user is not null
    AND (INITDATE >= TO_DATE('2016-12-01 00:00', 'YYYY-MM-DD HH24:MI:SS')) 
    AND (INITDATE <= TO_DATE('2016-12-31 23:59', 'YYYY-MM-DD HH24:MI:SS')) 
    and (type, subtype, problem) in (
        ('aaa','bbb','ccc'),
        ('aaa','bbb','ddd')) --  ... etc
    group by to_char(INITDATE,'YYYY-MM-DD')
    

    【讨论】:

    • 过去几乎需要 3 秒的查询,现在减少到不到 1 秒。非常感谢:)
    猜你喜欢
    • 2023-04-01
    • 2015-04-27
    • 1970-01-01
    • 2016-06-09
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多