解码多列的最有效方法-DB2

时间:2018-11-12 21:02:15

标签: db2 decode db2-luw

我对DB2(和一般而言的SQL)还很陌生,并且在寻找一种有效的方法来对列进行解码方面遇到困难

当前,数据库中有许多表,其中大多数表的列数都很大,这些数字与具有实际值的表相对应。我们正在谈论9,500个不同的值(例如“ 502 =是”或“ 1413 =研究生”)

在任何情况下,我都只执行WHERE子句并显示它们相等的位置,但是由于每个表需要解码20至30列,因此我无法做到这一点(据我所知)。

有没有一种方法可以有效地仅显示另一个表中的相应值?

示例:

SELECT TEST_ID, DECODE(TEST_STATUS, 5111, 'Approved, 5112, 'In Progress') TEST_STATUS
FROM TEST_TABLE

上面的方法工作正常。......但是我手动查找数字并查看它们以构建语句。正如我提到的,有些表有20-30列需要此列,而另一些表则需要12-15个条件的DECODE语句。

有什么可以让我做得更简单的事情了吗?

SELECT TEST_ID, DECODE(TEST_STATUS = *TableWithCodeValues*) TEST_STATUS
FROM TEST_TABLE

编辑:另外,更清楚地说,我知道我可以进行大量的INNER JOINS,但我不确定是否有比这更有效的方法。

2 个答案:

答案 0 :(得分:2)

从逻辑角度来看,我会考虑将查找表拆分为几个域/维度表。不知道这是否有可能为您做,所以我将剩下的部分。

如我的评论中所述,我将避免使用您的帖子中所述的DECODE。我将从像平常的联接一样开始:

SELECT a.TEST_STATUS
     , b.TEST_STATUS_DESCRIPTION
     , a.ANOTHER_STATUS
     , c.ANOTHER_STATUS_DESCRIPTION
     , ...
FROM TEST_TABLE as a
JOIN TEST_STATUS_TABLE as b
    ON a.TEST_STATUS = b.TEST_STATUS
JOIN ANOTHER_STATUS_TABLE as c
    ON a.ANOTHER_STATUS = c.ANOTHER_STATUS
JOIN ...

如果事情太慢,您可以尝试以下几种方法:

  • 创建一个统计视图,可以帮助确定联接的基数(可能有助于优化程序创建更好的计划):

https://www.ibm.com/support/knowledgecenter/sl/SSEPGG_9.7.0/com.ibm.db2.luw.admin.perf.doc/doc/c0021713.html

  • 如果您的许可证允许,您可以尝试使用物化查询表(MQT)。请注意,修改基表会受到惩罚,因此,如果您有更多的OLTP工作负载,这可能不是一个好主意:

https://www.ibm.com/developerworks/data/library/techarticle/dm-0509melnyk/index.html

如果您的查找表相当静态,第三个选择是将查找表缓存在应用程序中。从数据库中读取TEST_TABLE,并在应用程序中查找描述。进一步的改进可能是添加了一些触发器,这些触发器在修改查找表时会使缓存无效。

答案 1 :(得分:0)

如果您不想执行所有这些连接,则可以创建自己的LOOKUP函数。

create or replace function lookup(IN_ID INTEGER)
returns varchar(32) 
deterministic reads sql data 
begin atomic 
declare OUT_TEXT varchar(32);-- 
set OUT_TEXT=(select text from test.lookup where id=IN_ID);-- 
return OUT_TEXT;-- 
end;

带有表TEST.LOOKUP之类的

create table test.lookup(id integer, text varchar(32))

包含一些id / text对,这将返回与id对应的文本值..如果未找到NULL。

有了您提到的1万个ID /文本对和ID字段上的索引,这不应该成为性能问题,因为这样的数据量应该容易地缓存在相应的缓冲池中。