programing

Oracle에는 필터링된 인덱스 개념이 있습니까?

codeshow 2023. 8. 10. 21:41
반응형

Oracle에는 필터링된 인덱스 개념이 있습니까?

SQL Server와 유사하게 다음 작업을 수행할 수 있습니다.

create index TimeSeriesPeriodSs1 on TimeSeriesPeriod (validationStatus, completionStatus)
where completionStatus= N'Complete'  
and  validationStatus= N'Pending'

NULL 값이 b-tree 인덱스에 저장되지 않는다는 사실을 활용하는 함수 기반 인덱스를 Oracle에서 생성할 수 있습니다.비슷한 것

CREATE INDEX TimeSeriesPeriodSs1
    ON TimeSeriesPeriod( 
          (CASE WHEN completionStatus = 'Complete' AND validationStatus = 'Pending'
                THEN validationStatus
                ELSE NULL
            END),
          (CASE WHEN completionStatus = 'Complete' AND validationStatus = 'Pending'
                THEN completionStatus
                ELSE NULL
            END)
       );

이 경우 기능 기반 인덱스를 사용할 수 있지만 이 시나리오에서는 그다지 적합하지 않습니다.

create index TimeSeriesPeriodSs1 on TimeSeriesPeriod (
    case when validationStatus= N'Pending' and completionStatus= N'Complete' then validationStatus else null end,
    case when validationStatus= N'Pending' and completionStatus= N'Complete' then completionStatus else null end);

당신은 쿼리를 작성해야 합니다.where하지만 인덱스를 사용하기 위해 절이 정확히 일치합니다.

select <fields>
from TimeSeriesPeriod
where case when validationStatus= N'Pending' and completionStatus= N'Complete' then validationStatus else null end = N'Pending'
and case when validationStatus= N'Pending' and completionStatus= N'Complete' then completionStatus else null end = N'Complete';

만약 당신이 (결정론적) 함수를 정의할 수 있다면 이것은 훨씬 더 깔끔할 것입니다.case자세한 내용과 예제는 여기를 참조하십시오.아니면, 빠른 구글에서 가져온 것입니다.

다음은 인덱스 공간을 더 절약하고 수정된 쿼리를 IMO를 더 읽기 쉽게 만들 수 있는 Justin과 Alex의 답변에 대한 작은 변형입니다.

CREATE INDEX TimeSeriesPeriodSs1
    ON TimeSeriesPeriod( 
          (CASE WHEN completionStatus = 'Complete' AND validationStatus = 'Pending'
                THEN 1
                ELSE NULL
           END);

SELECT * FROM TimeSeriesPeriod
  WHERE 1 = (CASE WHEN completionStatus = 'Complete' AND validationStatus = 'Pending'
                THEN 1
                ELSE NULL
             END)

기능 기반 인덱스에 대한 잠재적인 대안/개선 사항은 가상 열을 사용하는 것입니다.

create table TimeSeriesPeriod (
  --...
  pendingValidation as (
    case when completionStatus = N'Complete' and validationStatus= N'Pending'
      then 1
    else null
  ) virtual
);
create index TimeSeriesPeriodSs1 on TimeSeriesPeriod (pendingValidation);

select * from TimeSeriesPeriod where pendingValidation = 1;

가상 열/함수 기반 인덱스에 대한 통계는 일반 열과 마찬가지로 수집되므로 비용이 0이 아닙니다.가능한 경우 여러 필터를 단일 가상 열로 축소하는 것을 고려합니다.

create table TimeSeriesPeriod (
  --...
  incompleteValidationStatus as (
    case when completionStatus = N'Complete' and validationStatus != N'Complete'
      then validationStatus
    else null
  ) virtual
);
create index TimeSeriesPeriodSs1 on TimeSeriesPeriod (incompleteValidationStatus);

select * from TimeSeriesPeriod where incompleteValidationStatus = N'Pending';
select * from TimeSeriesPeriod where incompleteValidationStatus = N'Failed Validation';

언급URL : https://stackoverflow.com/questions/5939776/does-oracle-have-a-filtered-index-concept

반응형