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

Most efficient way to DECODE multiple columns -- DB2

我是 DB2 的新手(一般来说 SQL),我很难找到一种有效的方法来解码列

目前,数据库中有许多table,其中大部分都有大量的列作为数字,这些数字对应于具有真实值的table。我们说的是 9,500 个不同的值(例如“502=yes”或“1413= Graduate Student”)

在任何情况下,我都会执行 WHERE 子句并显示它们相等的位置,但是由于每个 table 需要解码 20-30 列,我真的不能这样做(我知道的)。

有没有办法有效地只显示来自另一个table的相应值?

示例:

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

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

有没有什么可以让我做一些更简单的事情,比如:

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

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

从逻辑的角度来看,我会考虑将查找 table 拆分为多个 domain/dimension table。不确定这是否可以为您做,所以我会留下那部分。

正如我在评论中提到的那样,我不会按照您 post 中的描述使用 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)。请注意,修改基础 tables 会受到惩罚,因此如果您有更多的 OLTP 工作负载,这可能不是一个好主意:

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

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

如果您不想进行所有这些联接,您可以自己创建一个 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;

有tableTEST.LOOKUP赞

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

包含一些 id/text 对,这将 return 文本值对应于一个 id .. 如果没有找到 NULL。

有了你提到的 10k id/text 对和 ID 字段上的索引,这应该不是性能问题,因为这样的数据量应该很容易缓存在相应的缓冲池中。