解码多列的最有效方法——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 ...
如果速度太慢,您可以尝试以下几种方法:
- 创建统计视图以帮助确定连接的基数(可能有助于优化器创建更好的计划):
- 如果您的许可证允许,您可以试验物化查询表 (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 字段上的索引,这应该不是性能问题,因为这样的数据量应该很容易缓存在相应的缓冲池中。
我是 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 ...
如果速度太慢,您可以尝试以下几种方法:
- 创建统计视图以帮助确定连接的基数(可能有助于优化器创建更好的计划):
- 如果您的许可证允许,您可以试验物化查询表 (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 字段上的索引,这应该不是性能问题,因为这样的数据量应该很容易缓存在相应的缓冲池中。