Oracle: разбить данные по разделителю на несколько столбцов и показать каждую строку - PullRequest
0 голосов
/ 21 сентября 2018

Я хочу разбить строку данных каждого столбца на основе разделителя и показать в несколько строк.Мне нужен самый быстрый способ добиться этого.Моя схема и текущий запрос на разделение записей, как показано ниже:

CREATE TABLE APP_SPECS
  (
    SPEC_ID          NUMBER PRIMARY KEY,
    SPEC_NAME        VARCHAR2(4000),
    SPEC_DESCRIPTION VARCHAR2(4000),
    SPEC_TYPE        VARCHAR2(4000)
  );
/
INSERT INTO APP_SPECS VALUES (1, 'SPEC 1' || CHR(10) || 'SPEC 2', 'SPEC DESC' || CHR(10) || 'SPEC DESC', 'TYPE 1' || CHR(10) || 'TYPE 2');
/
INSERT INTO APP_SPECS VALUES (2, 'SPEC 3' || CHR(10) || 'SPEC 4', 'SPEC DESC 3' || CHR(10) || 'SPEC DESC 4', 'TYPE 3' || CHR(10) || 'TYPE 4');
/
INSERT INTO APP_SPECS VALUES (3, 'SPEC 5' || CHR(10) || 'SPEC 6', CHR(10) || 'SPEC DESC 6', 'TYPE 5' || CHR(10) || 'TYPE 6');
/
INSERT INTO APP_SPECS VALUES (4, 'SPEC 7' || CHR(10) || 'SPEC 8' || CHR(10) || 'SPEC 9', 'SPEC DESC 7', 'TYPE 7' || CHR(10) || 'TYPE 8');
/
COMMIT;
/

Запрос на разделение с использованием таблицы:

WITH APP_SPECS_CTE AS
  (SELECT REGEXP_SUBSTR(REPLACE(SPEC.SPEC_NAME,CHR(10),','), '[^,]+', 1, LEVEL) SPEC_NAME ,
    REGEXP_SUBSTR(REPLACE(SPEC.SPEC_DESCRIPTION,CHR(10),','), '[^,]+', 1, LEVEL) SPEC_DESCRIPTION ,
    REGEXP_SUBSTR(REPLACE(SPEC.SPEC_TYPE,CHR(10),','), '[^,]+', 1, LEVEL) SPEC_TYPE,
    SPEC_ID
  FROM APP_SPECS SPEC
    CONNECT BY LEVEL          <= LENGTH(REPLACE(SPEC.SPEC_NAME,CHR(10),',')) - LENGTH(REPLACE(REPLACE(SPEC.SPEC_NAME,CHR(10),','), ',')) + 1
  AND PRIOR SPEC_ID            = SPEC_ID
  AND PRIOR DBMS_RANDOM.VALUE IS NOT NULL
  )
SELECT SPEC_ID, SPEC_NAME, SPEC_DESCRIPTION, SPEC_TYPE FROM APP_SPECS_CTE;

, используя запрос выше, мы получим вывод ниже.

| SPEC_ID | SPEC_NAME | SPEC_DESCRIPTION | SPEC_TYPE |
|---------|-----------|------------------|-----------|
| 1       | SPEC 1    | SPEC DESC        | TYPE 1    |
| 1       | SPEC 2    | SPEC DESC        | TYPE 2    |
| 2       | SPEC 3    | SPEC DESC 3      | TYPE 3    |
| 2       | SPEC 4    | SPEC DESC 4      | TYPE 4    |
| 3       | SPEC 5    | SPEC DESC 6      | TYPE 5    |
| 3       | SPEC 6    | null             | TYPE 6    |
| 4       | SPEC 7    | SPEC DESC 7      | TYPE 7    |
| 4       | SPEC 8    | null             | TYPE 8    |
| 4       | SPEC 9    | null             | null      |

У меня есть 3 миллиона записей в моей таблице APP_SPEC.когда я выполняю это занимает 5+ минут.Может ли кто-нибудь проверить мой запрос и исправить меня, если что-то не так.

Детали экземпляра Oracle: процессор Octa core, 64 ГБ ОЗУ.

1 Ответ

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

Я хочу, чтобы запрос выполнялся менее чем за 10 с.

Запрос 3 миллионов записей менее чем за десять секунд сам по себе довольно сложен.Еще до того, как мы рассмотрим обработку регулярных выражений с интенсивным использованием процессора.Отображение этого количества строк в пользовательском интерфейсе?Невозможно.Но на самом деле это кратно 3 м, потому что вы разбиваете каждую запись на несколько строк.Так что на самом деле это невозможно.

Но каково здесь реальное требование?Ваши пользователи действительно хотят видеть все три миллиона строк каждый раз?Или они действительно будут запрашивать небольшое подмножество строк, например, для SPEC_ID?Потому что это должно быть возможно менее чем за десять секунд.

Но если вам нужно выполнить запрос ко всей таблице, нет способа сделать это за гораздо меньшее время, чем это уже требуется.Вам нужно будет реорганизовать вашу модель данных в Первую нормальную форму.Для этого может потребоваться не так много усилий, как вы думаете: вы можете использовать представление, чтобы поддерживать текущую проекцию для более совершенной модели данных, столько времени, сколько потребуется для рефакторинга пользовательского интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...