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

解码多列的最有效方法——DB2,db2,decode,db2-luw,Db2,Decode,Db2 Luw,我对DB2(以及一般的SQL)相当陌生,我很难找到一种有效的方法来解码列 目前,数据库中有许多表,其中大多数表的列都有相当数量的数字,这些数字对应一个具有实值的表。我们讨论的是9500个不同的值(例如“502=是”或“1413=研究生”) 在任何情况下,我都只需要执行WHERE子句并显示它们相等的位置,但由于每个表有20-30列需要解码,所以我无法真正做到这一点(据我所知) 是否有一种方法可以有效地显示另一个表中的相应值 例如: SELECT TEST_ID, DECODE(TEST_STATU

我对DB2(以及一般的SQL)相当陌生,我很难找到一种有效的方法来解码列

目前,数据库中有许多表,其中大多数表的列都有相当数量的数字,这些数字对应一个具有实值的表。我们讨论的是9500个不同的值(例如“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个条件的解码语句

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

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

<强>编辑:,更清楚地说,我知道我可以做大量的内部连接,但我不确定是否有一种更有效的方法。

< P>从逻辑的观点来看,我会考虑把查找表分割成几个域/维度表。我不确定这是否能帮到你,所以我就不谈了

正如我在评论中提到的,我不会像你在文章中描述的那样使用解码。我会像往常一样开始:

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 ...
如果速度太慢,可以尝试以下几种方法:

  • 创建一个统计视图,该视图有助于从联接中确定基数(可能有助于优化器创建更好的计划):

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


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

< P>从逻辑的角度来看,我会考虑将查找表分割成若干个域/维度表。我不确定这是否能帮到你,所以我就不谈了

正如我在评论中提到的,我不会像你在文章中描述的那样使用解码。我会像往常一样开始:

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 ...
如果速度太慢,可以尝试以下几种方法:

  • 创建一个统计视图,该视图有助于从联接中确定基数(可能有助于优化器创建更好的计划):

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


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

如果您不想执行所有这些连接,您可以自己创建一个查找函数

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/文本对,这将返回与id对应的文本值。。如果未找到,则为NULL


对于您提到的10k id/文本对和id字段上的索引,这不应该是一个性能问题,因为这样的数据量应该很容易缓存在相应的缓冲池中。

如果您不想进行所有这些连接,您可以自己创建一个查找函数

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/文本对,这将返回与id对应的文本值。。如果未找到,则为NULL


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

是所有查找值都在一个表中,还是查询中的每一列都有一个查找表?不管怎样,我都不会使用DECODE,因为从长远来看,这将是一场噩梦。我想到的是,如果一个维度用另一个值扩展,“进行中”应该更改为其他值,或者如果决定您必须支持另一种语言,那么所有值都存在于一个表中。因此,所有9500个可能的代码都可以通过对单个表进行连接来找到。我不知道你所说的“如果一个维度扩展了另一个值”是什么意思。如果向该表添加了另一个值,那么如果使用decode,你将不得不更改所有查询。这正是我不想使用decode的原因。我也需要为未来的价值观做准备。有些将只有2-3个值,它们不会更改,但其他将有一组值,并且可以更改。是所有查找值都在一个表中,还是查询中的每一列都有一个查找表?不管怎样,我都不会使用DECODE,因为从长远来看,这将是一场噩梦。我想到的是,如果一个维度用另一个值扩展,“进行中”应该更改为其他值,或者如果决定您必须支持另一种语言,那么所有值都存在于一个表中。因此,所有9500个可能的代码都可以通过对单个表进行连接来找到。我不知道你所说的“如果一个维度扩展了另一个值”是什么意思。如果向该表添加了另一个值,那么如果使用decode,你将不得不更改所有查询。这正是我不想使用decode的原因。我也需要为未来的价值观做准备。有些只有2-3个值,它们不会改变,但另一些会有一堆值