Самый эффективный способ ДЕКОДИРОВАНИЯ нескольких столбцов - DB2 - PullRequest
0 голосов
/ 13 ноября 2018

Я довольно новичок в DB2 (и в целом в SQL), и у меня возникают проблемы с поиском эффективного метода для столбцов DECODE

В настоящее время в базе данных имеется ряд таблиц, большинство из которых имеют значительное количество столбцов в виде чисел, эти числа соответствуют таблице с действительными значениями. Мы говорим о 9500 различных значениях (например, «502 = да» или «1413 = аспирант»)

В любой ситуации я бы просто сделал предложение WHERE и показал бы, где они равны, но, поскольку для каждой таблицы нужно декодировать 20-30 столбцов, я не могу этого сделать (что я знаю).

Есть ли способ эффективно отобразить соответствующее значение из другой таблицы?

Пример:

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

Вышеописанное работает нормально ....... но я вручную просматриваю числа и проверяю их, чтобы составить утверждения. Как я уже упоминал, в некоторых таблицах есть 20-30 столбцов, для которых это необходимо, а в некоторых - операторы DECODE, которые будут состоять из 12-15 условий.

Есть ли что-нибудь, что позволило бы мне сделать что-то попроще, например:

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

РЕДАКТИРОВАТЬ: Кроме того, чтобы быть более ясным, я знаю, что могу сделать тонну ВНУТРЕННИХ СОЕДИНЕНИЙ, но я не был уверен, был ли более эффективный способ, чем это.

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Если вы не хотите выполнять все эти объединения, вы можете создать собственную функцию 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, которое вернет текстовое значение, соответствующее идентификатору, если не найдено NULL.

С вашими упомянутыми парами идентификаторов / текстов по 10 тыс. И индексом в поле идентификатора это не должно быть проблемой производительности, поскольку такой объем данных должен легко кэшироваться в соответствующем пуле буферов.

0 голосов
/ 13 ноября 2018

С логической точки зрения я хотел бы рассмотреть разбиение таблицы поиска на несколько таблиц доменов / измерений. Не уверен, что это можно сделать для вас, поэтому я оставлю эту часть.

Как уже упоминалось в моем комментарии, я бы не использовал 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 из базы данных и посмотрите описания в приложении. Дальнейшие улучшения могут заключаться в добавлении триггеров, которые делают недействительным кеш при изменении таблицы поиска.

...