2016-10-12 4 views
-1

역할 열이있는 사용자 테이블이 있습니다. 각 사용자는 여러 개의 역할을 가질 수 있으며, 사용하기 쉽도록 쉼표로 구분 된 목록을 사용하여 역할을 저장할 수 있습니다.쉼표로 구분 된 문자열을 행으로 구문 분석합니다.

SELECT DISTINCT username, 
    trim(regexp_substr(str, '[^,]+', 1, level)) authority 
FROM 
    (SELECT username, role str FROM user WHERE role IS NOT NULL 
) roles_table 
CONNECT BY instr(str, ',', 1, level - 1) > 0 

:

USERNAME ROLE 
---------------------- 
bob  role1,role2 
sally  role2 

이제 특정 역할을 확인하기 위해 필요, 나는 다음과 같은 부속을 사용하여 (기본 XREF 테이블과 유사) 사용자 역할 매핑을 얻을 수있는 뷰를 만들었습니다 얻을 수

USERNAME AUTHORITY 
---------------------- 
bob  role1 
bob  role2 
sally  role2 

문제는이 하위 쿼리를 실행하는 데 과도한 시간이 걸리는 것입니다. 프로세스를 최적화하기 위해 서식을 지정하는 더 좋은 방법이 있습니까?

아니면 전체 구조를 업데이트하고 XREF 테이블을 사용하도록 되돌릴 필요가 있습니까? 후자의 경우 XREF보기를 만들고 색인을 사용하여 속도를 높일 수 있습니까?

감사합니다.

+1

그리고 Dr. Codd가 첫 번째 정상적인 형식을 사용했기 때문에 이러한 이유가 있습니다. – danihp

+1

중복 된 것입니다 : http://stackoverflow.com/questions/14328621/splitting-string-into-multiple-rows-in-oracle – Kacper

답변

1

입력이 CLOB이고 instr 및 substr의 dbms_lob 버전을 사용하면 instr 및 substr (정규 표현식 버전이 아닌)을 사용하여 속도를 향상시킬 수 있습니다.

on commit refresh fast으로 구체화 된보기를 작성할 수 있습니다 (기본 테이블에서의 트랜잭션을 약간 느리게하는 대신).

최선의 선택은 기본 표를 첫 번째 정규 양식 (본질적으로 현재보기의 RESULT)으로 대체하는 것입니다. 그러나 아마도 이것은 선택 사항이 아닙니다.

EDIT : 방금 쿼리를 다시 보았고 현재 수행중인 작업을 확인했습니다. 계층 적 쿼리를 작성한 방식에 따라 지나치게 많은 수의 행이 생성되고 DISTINCT를 사용하여 줄이게됩니다. 먼저이 기능을 사용해보십시오.

select username, trim(regexp_substr(str, '[^,]+', 1, level)) authority 
from user 
connect by instr(str, ',', 1, level - 1) > 0 
     and prior username = username 
     and prior sys_guid() is not null; 
+0

대단하군요,이 시간이 극적으로 빨라집니다! XREF 테이블을 포함하도록 구조체를 다시 작성하려고했지만이 작업으로 인해 모든 작업이 절약됩니다. 감사! – vinays84

+0

= 275x 빠른 속도 – vinays84

관련 문제