문자 값이 암시적 데이터 변환에 의해 날짜 값으로 변환되면 INTERNAL_FUNCTION로 표시되고 스토리지 인덱스를 사용할 수 없게 됩니다. 이와 관련하여 예전에 암시적 데이터 변환과 오프로딩 글을 작성했습니다. 앞서 작성한 IN 조건과 INTERNAL_FUNCTION 글도 INTERNAL_FUNCTION으로 표시된 IN 조건의 스토리지 인덱스 사용 여부에 대한 검증을 위해 작성했습니다.
테스트를 위해 아래와 같이 테이블을 생성하고, _serial_direct_read 파라미터를 ALWAYS로 설정하겠습니다.
-- 1-1
DROP TABLE t1 PURGE;
CREATE TABLE t1 (c1, c2, c3) NOLOGGING AS SELECT 1, CEIL (ROWNUM / 1000000), LPAD ('X', 100, 'X') FROM XMLTABLE ('1 to 10000000');
-- 1-2
ALTER SESSION SET "_serial_direct_read" = ALWAYS;
아래와 같이 두 쿼리를 수행하겠습니다. 2-1번 쿼리는 Predicate Information 항목에 INTERNAL_FUNCTION이 표시되고, 2-2번 쿼리는 좌변이 가공된 OR 조건이 표시됩니다.
-- 2-1
SELECT COUNT (*) FROM t1 WHERE c1 = 1 AND c2 IN (1, 2);
------------------------------------------------------------------------------------
| Id | Operation | Name | A-Rows | A-Time | Buffers | Reads |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 |00:00:00.07 | 156K| 156K|
| 1 | SORT AGGREGATE | | 1 |00:00:00.07 | 156K| 156K|
|* 2 | TABLE ACCESS STORAGE FULL| T1 | 2000K|00:00:00.07 | 156K| 156K|
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - storage((INTERNAL_FUNCTION("C2") AND "C1"=1))
filter((INTERNAL_FUNCTION("C2") AND "C1"=1))
-- 2-2
SELECT COUNT (*) FROM t1 WHERE c1 = 1 AND c2 + 0 IN (1, 2);
------------------------------------------------------------------------------------
| Id | Operation | Name | A-Rows | A-Time | Buffers | Reads |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 |00:00:00.17 | 156K| 156K|
| 1 | SORT AGGREGATE | | 1 |00:00:00.17 | 156K| 156K|
|* 2 | TABLE ACCESS STORAGE FULL| T1 | 2000K|00:00:00.17 | 156K| 156K|
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - storage((("C2"+0=1 OR "C2"+0=2) AND "C1"=1))
filter((("C2"+0=1 OR "C2"+0=2) AND "C1"=1))
아래는 세션 통계 값을 비교한 결과입니다. 2-1번 쿼리는 storage index를 사용하고, 2-2번 쿼리는 사용하지 않은 것을 확인할 수 있습니다.
-- 3
+-----------------------------------------------------------+----------+----------+------+
|NAME | # 2-1| # 2-2|CLASS |
+-----------------------------------------------------------+----------+----------+------+
|cell physical IO bytes eligible for smart IOs | 1.19g| 1.19g|Cache |
|cell physical IO bytes saved by storage index | 976.48m| 0.00 |Cache | -- !
|cell physical IO bytes eligible for predicate offload | 1.19g| 1.19g|SQL |
|cell physical IO interconnect bytes | 23.92m| 24.23m|SQL |
|cell physical IO interconnect bytes returned by smart scan | 23.92m| 24.23m|SQL |
+-----------------------------------------------------------+----------+----------+------+