2009년 2월 27일 금요일
[SW 글로벌 스타를 향해] (6-1부) ⑤ 세계 일류를 지향하라
이런 상품을 개발하는 것이 바로 기업의 꿈이다. 필요한 제품일수록, 흔치 않을수록 수요가 높기 때문이다. 흔치 않기 때문에 이익도 더 많이 거둘 수 있다. 우리나라도 이런 소프트웨어(SW)를 개발하는 것이 가능할까. 이런 SW만 개발하면 세계 시장을 주름잡는 것은 문제없을 듯하다.
SW 분야에서는 후진국으로 불리는 우리나라기에 꿈 같은 이야기로만 들린다. 그러나, 우리나라도 이런 SW를 개발하는 기업이 여럿 있다. 아직은 세계 시장에서 잘 알려지지 않았지만, 기반을 다지고 브랜드를 알려간다면 충분히 승산이 있다. '필요하지만 흔치 않은 SW'를 개발하고 있기 때문이다.
◇세계에서 몇 안 되는 우리 SW=데이터를 갖고 있는 모든 기업과 기관의 필수 SW로 자리 잡은 데이터베이스관리시스템(DBMS). 이 분야에서 한국이 상당한 위상을 갖고 있다는 사실을 아는 사람은 흔치 않다. 심지어 국내에서도 오라클과 같은 글로벌 기업이 시장을 주름 잡고 있어서다.
그러나 시스템의 핵심으로 쓰이는 DBMS를 개발하는 기업이 있는 나라는 오라클과 MS가 있는 미국을 제외하면 사실상 한국이 유일하다.
엔터프라이즈 SW 분야에서 가장 중요하다는 DBMS의 핵심 기술을 보유한 나라가 미국과 한국이라는 뜻이다. 그것도 쟁쟁한 기업들이 4개나 있다. 알티베이스·큐브리드·티맥스소프트·리얼타임테크가 그 주인공이다. 오라클과 MS보다 규모가 작고 개발 역사가 짧아서 아직 세계시장에서 어깨를 겨루지는 못하지만, 세계 시장에서 이들을 알아주기 시작한다면 그 성장률은 엄청날 것으로 기대된다.
세계 DBMS 시장은 현재 233억달러 규모로 추정되고 있으며, 2016년에는 연평균 8%가량 성장해 432억달러에 달할 것으로 기대된다. 이 중 1%만 해도 4억달러(6000억원) 규모다. 기업들이 다각화될수록 경쟁으로 인해 고객들은 가격과 성능 면에서 많은 이익을 취할 수 있다는 점에서, 세계시장에서도 국내 DBMS 기업들의 진출은 유익한 일이다.
DBMS뿐이 아니다. 보안 분야에서는 한국 기업들이 세계적인 경쟁력을 갖고 있는 사례가 많다. 문서의 중요한 정보가 외부로 유출되는 것을 막는 문서보안 DRM은 세계적으로도 플레이어가 몇 안 된다. 게다가 해외 DRM 시장은 이미 2005년 본격적인 성숙기에 접어들었지만, 상대적으로 부각되고 있는 선두기업은 아직 출현하지 않고 있는 상황이다. 승부를 걸어 볼 만한 분야라는 것이다.
글로벌 DRM 솔루션 기업으로는 어도비와 EMC, 오라클 등 대형 기업용 콘텐츠관리(ECM) 기업들이 DRM 전문 기업을 인수합병하면서 DRM 단독 기능보다는 전체 보안 인프라의 핵심 기능의 일환으로 DRM 기술을 활용하고 있는 추세다. 현재까지 DRM에만 집중하고 있는 대표적인 기업으로는 미국 DRM 기업인 리퀴드머신스 정도를 꼽을 수 있다.
이에 비해 국내에서는 마크애니·파수닷컴·소프트캠프·두루안 등 전문기업이 승승장구하고 있다. 해외에서도 성과를 올리기 시작하고 있다. 이들 기업은 중국·인도네시아 등지로 DRM 수출을 진행하면서 브랜드도 차츰 알려가는 상황이다.
파수닷컴은 정부 공공기관과 주요 대기업은 물론이고 제조, 금융, 인터넷포털 등 국내외 다양한 업종 650여기업에 DRM 솔루션 및 서비스를 공급하며 세계 최다 구축 레퍼런스를 보유하고 있다. 이 회사는 세계적으로 SW 테스팅 관련 이슈가 부각될 것으로 전망하고 프로그램분석툴인 스패로우도 개발해 주목을 받은 바 있다.
마크애니는 인도네시아 시장에서 이름을 알리고 올해 매출 200억원 돌파를 앞두고 있다. 마크애니의 워터마킹 솔루션도 주목받는 분야다. 워터마킹은 누가 어디에서 문서와 정보를 유출했는지를 추출해 낼 수 있는 기술이다. 최근에는 음반 분야에서도 큰 관심을 기울이면서 세계적으로 주목받는 SW가 됐지만, 세계적으로 전문 기업이 톰슨. 디지마크.필립스 등 5개밖에 없다.
세계 일류 상품도 주목할 만하다. 지식경제부는 매년 세계 일류 상품을 선정하고 있다. 세계시장 점유율이 5위 이내에 들어가는 점 등을 인정해 지식경제부 장관이 '세계일류상품 선정 및 제도운영에 관한 요령' 제7조 및 제8조의 규정에 의해 선정한다. 2000년 초반까지만 해도 이들 일류상품에는 반도체와 부품을 비롯한 HW가 모두 휩쓸었다. 그러나, 2005년 DRM 솔루션과 컴퓨터 바이러스퇴치 SW(백신)가 처음으로 일류상품에 지정됐다.
이후로, 2007년에는 메인 메모리 DBMS와 무선공개키 기반구조 인증시스템이 선정됐으며, 반도체 제조공정 결함분석 SW 중소제조업용 생산정보화SW 그 중요성과 세계 시장 점유율을 인정받아 지정됐다. 2008년에는 토목·건축 구조해석 및 설계용 소프트웨어가 대한민국이 보유한 세계 일류상품에 선정됐다.
◇한국 레퍼런스 무엇보다 중요, 정부가 먼저 국산 SW 사용해야 = 세계 시장에서 겨뤄볼 만한 제품들이 있지만, 이들이 세계 시장에서 진정한 펼치는 데 가장 큰 지원군은 바로 국내 레퍼런스다.
국내 공공기관, 국내 대기업이 이들 제품을 얼마나 잘 써줬는지에 따라 세계 시장에서도 이들의 성패가 판가름난다 해도 과언이 아니다. 모바일용 SW 분야에서 국내 삼성전자와 LG전자의 휴대폰에 채택됐다는 것만으로 세계 휴대폰 업체들이 어느 정도 실력을 인정해주는 것과 같은 이치다. 정부가 SW 수출 지원을 위해서는 누구보다 앞장서 국산 SW를 사용하는 것이 가장 빠른 길이라는 시각도 이러한 관점에서 나온다.
DBMS를 중국에 수출한 알티베이스도 국내 주요 통신사 레퍼런스가 없었다면 수출이 불가능했다고 강조했다.
"제품이 좋다고 무턱대고 외국 나가서는 성공할 수 없고 국내에서 중요한 레퍼런스를 쌓아야 해외에서도 대접받는다"는 김기완 알티베이스 사장은 "중국에 수출을 그동안 많이 해 왔는데 그것은 중국 고객이 우리 제품을 믿어서가 아니라 우리나라가 앞서있는 통신 인프라에서 검증된 것이라서 쓴 것"이라고 말했다.
또, "중국과 일본은 가깝고 풍토가 비슷해 일단 수출을 할 수 있는 여건이 된다"며 "중국과 일본을 공략해서 올해 수출을 매출 대비 20%까지 확대하는 것이 목표"라고 덧붙였다.
국내 레퍼런스는 세계 시장에서 충분히 마케팅을 할 수 있는 여력을 만들어주기도 한다.
강태헌 한일IT경영협의회장은 "해외에 나가기 위해서는 홍보를 하기 위해서도 또 오랫동안 싸울 체력을 기르기 위해서도 국내 사업 기반이 무엇보다 중요하다"며 "공공기관이 앞장서 국내 제품을 사용하는 것은 여러모로 수출 장려에 도움이 된다"고 설명했다.
문보경기자 okmun@etnews.co.kr
'No.1 IT 포털 ETNEWS'
Copyright ⓒ 전자신문 & 전자신문인터넷, 무단전재 및 재배포 금지
http://media.daum.net/digital/others/view.html?cateid=100031&newsid=20090227142117185&p=etimesi
2009년 2월 23일 월요일
2009년 2월 17일 화요일
V$SQL / V$SQL_WORKAREA
V$SQL
V$SQL
lists statistics on shared SQL areas without the GROUP BY
clause and contains one row for each child of the original SQL text entered. Statistics displayed in V$SQL
are normally updated at the end of query execution. However, for long running queries, they are updated every 5 seconds. This makes it easy to see the impact of long running SQL statements while they are still in progress.
Column | Datatype | Description |
---|---|---|
SQL_TEXT | VARCHAR2(1000) | First thousand characters of the SQL text for the current cursor |
SQL_FULLTEXT | CLOB | Full text for the SQL statement exposed as a CLOB column. The full text of a SQL statement can be retrieved using this column instead of joining with the V$SQLTEXT dynamic performance view. |
SQL_ID | VARCHAR2(13) | SQL identifier of the parent cursor in the library cache |
SHARABLE_MEM | NUMBER | Amount of shared memory used by the child cursor (in bytes) |
PERSISTENT_MEM | NUMBER | Fixed amount of memory used for the lifetime of the child cursor (in bytes) |
RUNTIME_MEM | NUMBER | Fixed amount of memory required during the execution of the child cursor |
SORTS | NUMBER | Number of sorts that were done for the child cursor |
LOADED_VERSIONS | NUMBER | Indicates whether the context heap is loaded (1 ) or not (0 ) |
OPEN_VERSIONS | NUMBER | Indicates whether the child cursor is locked (1 ) or not (0 ) |
USERS_OPENING | NUMBER | Number of users executing the statement |
FETCHES | NUMBER | Number of fetches associated with the SQL statement |
EXECUTIONS | NUMBER | Number of executions that took place on this object since it was brought into the library cache |
PX_SERVERS_EXECUTIONS | NUMBER | Total number of executions performed by parallel execution servers (0 when the statement has never been executed in parallel) |
END_OF_FETCH_COUNT | NUMBER | Number of times this cursor was fully executed since the cursor was brought into the library cache. The value of this statistic is not incremented when the cursor is partially executed, either because it failed during the execution or because only the first few rows produced by this cursor are fetched before the cursor is closed or re-executed. By definition, the value of the END_OF_FETCH_COUNT column should be less or equal to the value of the EXECUTIONS column. |
USERS_EXECUTING | NUMBER | Number of users executing the statement |
LOADS | NUMBER | Number of times the object was either loaded or reloaded |
FIRST_LOAD_TIME | VARCHAR2(19) | Timestamp of the parent creation time |
INVALIDATIONS | NUMBER | Number of times this child cursor has been invalidated |
PARSE_CALLS | NUMBER | Number of parse calls for this child cursor |
DISK_READS | NUMBER | Number of disk reads for this child cursor |
DIRECT_WRITES | NUMBER | Number of direct writes for this child cursor |
BUFFER_GETS | NUMBER | Number of buffer gets for this child cursor |
APPLICATION_WAIT_TIME | NUMBER | Application wait time (in microseconds) |
CONCURRENCY_WAIT_TIME | NUMBER | Concurrency wait time (in microseconds) |
CLUSTER_WAIT_TIME | NUMBER | Cluster wait time (in microseconds) |
USER_IO_WAIT_TIME | NUMBER | User I/O Wait Time (in microseconds) |
PLSQL_EXEC_TIME | NUMBER | PL/SQL execution time (in microseconds) |
JAVA_EXEC_TIME | NUMBER | Java execution time (in microseconds) |
ROWS_PROCESSED | NUMBER | Total number of rows the parsed SQL statement returns |
COMMAND_TYPE | NUMBER | Oracle command type definition |
OPTIMIZER_MODE | VARCHAR2(10) | Mode under which the SQL statement was executed |
OPTIMIZER_COST | NUMBER | Cost of this query given by the optimizer |
OPTIMIZER_ENV | RAW(2000) | Optimizer environment |
OPTIMIZER_ENV_HASH_VALUE | NUMBER | Hash value for the optimizer environment |
PARSING_USER_ID | NUMBER | User ID of the user who originally built this child cursor |
PARSING_SCHEMA_ID | NUMBER | Schema ID that was used to originally build this child cursor |
PARSING_SCHEMA_NAME | VARCHAR2(30) | Schema name that was used to originally build this child cursor |
KEPT_VERSIONS | NUMBER | Indicates whether this child cursor has been marked to be kept pinned in the cache using theDBMS_SHARED_POOL package |
ADDRESS | RAW(4 | 8) | Address of the handle to the parent for this cursor |
TYPE_CHK_HEAP | RAW(4) | Descriptor of the type check heap for this child cursor |
HASH_VALUE | NUMBER | Hash value of the parent statement in the library cache |
OLD_HASH_VALUE | NUMBER | Old SQL hash value |
PLAN_HASH_VALUE | NUMBER | Numeric representation of the SQL plan for this cursor. Comparing one PLAN_HASH_VALUE to another easily identifies whether or not two plans are the same (rather than comparing the two plans line by line). |
CHILD_NUMBER | NUMBER | Number of this child cursor |
SERVICE | VARCHAR2(64) | Service name |
SERVICE_HASH | NUMBER | Hash value for the name listed in the SERVICE column |
MODULE | VARCHAR2(64) | Contains the name of the module that was executing at the time that the SQL statement was first parsed, which is set by calling DBMS_APPLICATION_INFO.SET_MODULE |
MODULE_HASH | NUMBER | Hash value of the module listed in the MODULE column |
ACTION | VARCHAR2(64) | Contains the name of the action that was executing at the time that the SQL statement was first parsed, which is set by calling DBMS_APPLICATION_INFO.SET_ACTION |
ACTION_HASH | NUMBER | Hash value of the action listed in the ACTION column |
SERIALIZABLE_ABORTS | NUMBER | Number of times the transaction failed to serialize, producing ORA-08177 errors, per cursor |
OUTLINE_CATEGORY | VARCHAR2(64) | If an outline was applied during construction of the cursor, then this column displays the category of that outline. Otherwise the column is left blank. |
CPU_TIME | NUMBER | CPU time (in microseconds) used by this cursor for parsing, executing, and fetching |
ELAPSED_TIME | NUMBER | Elapsed time (in microseconds) used by this cursor for parsing, executing, and fetching |
OUTLINE_SID | NUMBER | Outline session identifier |
CHILD_ADDRESS | RAW(4 | 8) | Address of the child cursor |
SQLTYPE | NUMBER | Denotes the version of the SQL language used for this statement |
REMOTE | VARCHAR2(1) | Indicates whether the cursor is remote mapped (Y ) or not (N ) |
OBJECT_STATUS | VARCHAR2(19) | Status of the cursor:
|
LITERAL_HASH_VALUE | NUMBER | Hash value of the literals which are replaced with system-generated bind variables and are to be matched, when CURSOR_SHARING is used. This is not the hash value for the SQL statement. IfCURSOR_SHARING is not used, then the value is 0 . |
LAST_LOAD_TIME | VARCHAR2(19) | Time at which the query plan was loaded into the library cache |
IS_OBSOLETE | VARCHAR2(1) | Indicates whether the cursor has become obsolete (Y ) or not (N ). This can happen if the number of child cursors is too large. |
IS_BIND_SENSITIVE | VARCHAR2(1) | Indicates whether the cursor is bind sensitive (Y ) or not (N ). A query is considered bind-sensitive if the optimizer peeked at one of its bind variable values when computing predicate selectivities and where a change in a bind variable value may cause the optimizer to generate a different plan. |
IS_BIND_AWARE | VARCHAR2(1) | Indicates whether the cursor is bind aware (Y ) or not (N ). A query is considered bind-aware if it has been marked to use extended cursor sharing. The query would already have been marked as bind-sensitive. |
IS_SHAREABLE | VARCHAR2(1) | Indicates whether the cursor can be shared (Y ) or not (N ) |
CHILD_LATCH | NUMBER | Child latch number that is protecting the cursor. This column is obsolete and maintained for backward compatibility. |
SQL_PROFILE | VARCHAR2(64) | SQL profile used for this statement, if any |
SQL_PATCH | VARCHAR2(30) | SQL patch used for this statement, if any |
SQL_PLAN_BASELINE | VARCHAR2(30) | SQL plan baseline used for this statement, if any |
PROGRAM_ID | NUMBER | Program identifier |
PROGRAM_LINE# | NUMBER | Program line number |
EXACT_MATCHING_SIGNATURE | NUMBER | Signature calculated on the normalized SQL text. The normalization includes the removal of white space and the uppercasing of all non-literal strings. |
FORCE_MATCHING_SIGNATURE | NUMBER | Signature used when the CURSOR_SHARING parameter is set to FORCE |
LAST_ACTIVE_TIME | DATE | TIme at which the query plan was last active |
BIND_DATA | RAW(2000) | Bind data |
TYPECHECK_MEM | NUMBER | ??? |
V$SQL_WORKAREA
V$SQL_WORKAREA
displays information about work areas used by SQL cursors. Each SQL statement stored in the shared pool has one or more child cursors that are listed in the V$SQL
view. V$SQL_WORKAREA
lists all work areas needed by these child cursors; V$SQL_WORKAREA
can be joined with V$SQLAREA
on (ADDRESS
, HASH_VALUE
) and with V$SQL
on (ADDRESS
, HASH_VALUE
, CHILD_NUMBER
).
You can use this view to find out answers to the following questions:
- What are the top 10 work areas that require the most cache area?
- For work areas allocated in
AUTO
mode, what percentage of work areas are running using maximum memory?
Column | Datatype | Description |
---|---|---|
ADDRESS | RAW(4 | 8) | Address of the parent cursor handle |
HASH_VALUE | NUMBER | Hash value of the parent statement in the library cache. Two columns PARENT_HANDLE andHASH_VALUE can be used to join with V$SQLAREA to locate the parent cursor. |
SQL_ID | VARCHAR2(13) | SQL identifier of the parent statement in the library cache |
CHILD_NUMBER | NUMBER | Number of the child cursor that uses this work area. The columns PARENT_HANDLE , HASH_VALUE , andCHILD_NUMBER can be used to join with V$SQL to locate the child cursor using this area. |
WORKAREA_ADDRESS | RAW(4 | 8) | Address of the work area handle. This is the primary key for the view. |
OPERATION_TYPE | VARCHAR2(20) | Type of operation using the work area (SORT , HASH JOIN , GROUP BY , BUFFERING , BITMAP MERGE , orBITMAP CREATE ) |
OPERATION_ID | NUMBER | A unique number used to identify the operation in the execution plan. This identifier can be joined to V$SQL_PLAN to locate the operation that uses this work area. |
POLICY | VARCHAR2(10) | Sizing policy for this work area (MANUAL or AUTO ) |
ESTIMATED_OPTIMAL_SIZE | NUMBER | Estimated size (in bytes) required by this work area to execute the operation completely in memory (optimal execution). Derived from either optimizer statistics or previous executions. |
ESTIMATED_ONEPASS_SIZE | NUMBER | Estimated size (in bytes) required by this work area to execute the operation in a single pass. Derived from either optimizer statistics or previous executions. |
LAST_MEMORY_USED | NUMBER | Memory (in bytes) used by this work area during the last execution of the cursor |
LAST_EXECUTION | VARCHAR2(10) | Indicates whether this work area runs using OPTIMAL, ONE PASS , or ONE PASS memory requirement (or MULTI-PASS ), during the last execution of the cursor |
LAST_DEGREE | NUMBER | Degree of parallelism used during the last execution of this operation |
TOTAL_EXECUTIONS | NUMBER | Number of times this work area was active |
OPTIMAL_EXECUTIONS | NUMBER | Number of times this work area ran in optimal mode |
ONEPASS_EXECUTIONS | NUMBER | Number of times this work area ran in one-pass mode |
MULTIPASSES_EXECUTIONS | NUMBER | Number of times this work area ran below the one-pass memory requirement |
ACTIVE_TIME | NUMBER | Average time this work area is active (in hundredths of a second) |
MAX_TEMPSEG_SIZE | NUMBER | Maximum temporary segment size (in bytes) created by an instantiation of this work area. This column is NULL if this work area has never spilled to disk. |
LAST_TEMPSEG_SIZE | NUMBER | Temporary segment size (in bytes) created in the last instantiation of this work area. This column is NULL if the last instantiation of this work area did not spill to disk. |
7.5.1.2.6 V$SQL_WORKAREA
Oracle maintains cumulative work area statistics for each loaded cursor whose execution plan uses one or more work areas. Every time a work area is deallocated, theV$SQL_WORKAREA
table is updated with execution statistics for that work area.
V$SQL_WORKAREA
can be joined with V$SQL
to relate a work area to a cursor. It can even be joined to V$SQL_PLAN
to precisely determine which operator in the plan uses a work area.
Example 7-7 shows three typical queries on the V$SQL_WORKAREA
dynamic view:
Example 7-7 Querying V$SQL_WORKAREA
The following query finds the top 10 work areas requiring most cache memory:
SELECT * FROM ( SELECT workarea_address, operation_type, policy, estimated_optimal_size FROM V$SQL_WORKAREA ORDER BY estimated_optimal_size ) WHERE ROWNUM <= 10;
The following query finds the cursors with one or more work areas that have been executed in one or even multiple passes:
col sql_text format A80 wrap SELECT sql_text, sum(ONEPASS_EXECUTIONS) onepass_cnt, sum(MULTIPASSES_EXECUTIONS) mpass_cnt FROM V$SQL s, V$SQL_WORKAREA wa WHERE s.address = wa.address GROUP BY sql_text HAVING sum(ONEPASS_EXECUTIONS+MULTIPASSES_EXECUTIONS)>0;
Using the hash value and address of a particular cursor, the following query displays the cursor execution plan, including information about the associated work areas.
col "O/1/M" format a10 col name format a20 SELECT operation, options, object_name name, trunc(bytes/1024/1024) "input(MB)", trunc(last_memory_used/1024) last_mem, trunc(estimated_optimal_size/1024) optimal_mem, trunc(estimated_onepass_size/1024) onepass_mem, decode(optimal_executions, null, null, optimal_executions||'/'||onepass_executions||'/'|| multipasses_executions) "O/1/M" FROM V$SQL_PLAN p, V$SQL_WORKAREA w WHERE p.address=w.address(+) AND p.hash_value=w.hash_value(+) AND p.id=w.operation_id(+) AND p.address='88BB460C' AND p.hash_value=3738161960; OPERATION OPTIONS NAME input(MB) LAST_MEM OPTIMAL_ME ONEPASS_ME O/1/M ------------ -------- -------- --------- -------- ---------- ---------- ------ SELECT STATE HASH GROUP BY 4582 8 16 16 16/0/0 HASH JOIN SEMI 4582 5976 5194 2187 16/0/0 TABLE ACCESS FULL ORDERS 51 TABLE ACCESS FUL LINEITEM 1000
You can get the address and hash value from the V$SQL
view by specifying a pattern in the query. For example:
SELECT address, hash_value
FROM V$SQL
WHERE sql_text LIKE '%my_pattern%';
EXPLAIN PLAN 설정
Simple Explain Plan
SQL> set autotrace trace;
SQL> set autotrace off;
12.10 PLAN_TABLE Columns
The PLAN_TABLE
used by the EXPLAIN
PLAN
statement contains the columns listed in Table 12-1.
Table 12-1 PLAN_TABLE Columns
Column | Type | Description |
---|---|---|
|
| Value of the optional |
|
| Unique identifier of a plan in the database. |
|
| Date and time when the |
|
| Any comment (of up to 80 bytes) you want to associate with each step of the explained plan. This column is used to indicate whether an outline or SQL Profile was used for the query. If you need to add or change a remark on any row of the |
|
| Name of the internal operation performed in this step. In the first row generated for a statement, the column contains one of the following values:
See Table 12-3 for more information on values for this column. |
|
| A variation on the operation described in the See Table 12-3 for more information on values for this column. |
|
| Name of the database link used to reference the object (a table name or view name). For local queries using parallel execution, this column describes the order in which output from operations is consumed. |
|
| Name of the user who owns the schema containing the table or index. |
|
| Name of the table or index. |
|
| Unique alias of a table or view in a SQL statement. For indexes, it is the object alias of the underlying table. |
|
| Number corresponding to the ordinal position of the object as it appears in the original statement. The numbering proceeds from left to right, outer to inner with respect to the original statement text. View expansion results in unpredictable numbers. |
|
| Modifier that provides descriptive information about the object; for example, |
|
| Current mode of the optimizer. |
|
| Not currently used. |
|
| A number assigned to each step in the execution plan. |
|
| The ID of the next execution step that operates on the output of the |
|
| Depth of the operation in the row source tree that the plan represents. The value can be used for indenting the rows in a plan table report. |
|
| For the first row of output, this indicates the optimizer's estimated cost of executing the statement. For the other rows, it indicates the position relative to the other children of the same parent. |
|
| Cost of the operation as estimated by the optimizer's query approach. Cost is not determined for table access operations. The value of this column does not have any particular unit of measurement; it is merely a weighted value used to compare costs of execution plans. The value of this column is a function of the |
|
| Estimate by the query optimization approach of the number of rows accessed by the operation. |
|
| Estimate by the query optimization approach of the number of bytes accessed by the operation. |
|
| Describes the contents of the
|
|
| Start partition of a range of accessed partitions. It can take one of the following values: n indicates that the start partition has been identified by the SQL compiler, and its partition number is given by n.
|
|
| Stop partition of a range of accessed partitions. It can take one of the following values: n indicates that the stop partition has been identified by the SQL compiler, and its partition number is given by n.
|
|
| Step that has computed the pair of values of the |
|
| Other information that is specific to the execution step that a user might find useful. See the |
|
| Method used to distribute rows from producer query servers to consumer query servers. See Table 12-2 for more information on the possible values for this column. For more information about consumer and producer query servers, see Oracle Database Data Warehousing Guide. |
|
| CPU cost of the operation as estimated by the query optimizer's approach. The value of this column is proportional to the number of machine cycles required for the operation. For statements that use the rule-based approach, this column is null. |
|
| I/O cost of the operation as estimated by the query optimizer's approach. The value of this column is proportional to the number of data blocks read by the operation. For statements that use the rule-based approach, this column is null. |
|
| Temporary space, in bytes, used by the operation as estimated by the query optimizer's approach. For statements that use the rule-based approach, or for operations that do not use any temporary space, this column is null. |
|
| Predicates used to locate rows in an access structure. For example, start or stop predicates for an index range scan. |
|
| Predicates used to filter rows before producing them. |
|
| Expressions produced by the operation. |
|
| Elapsed time in seconds of the operation as estimated by query optimization. For statements that use the rule-based approach, this column is null. |
|
| Name of the query block, either system-generated or defined by the user with the |
12.2 The PLAN_TABLE Output Table
The PLAN_TABLE
is automatically created as a global temporary table to hold the output of an EXPLAIN
PLAN
statement for all users. PLAN_TABLE
is the default sample output table into which the EXPLAIN
PLAN
statement inserts rows describing execution plans. See "PLAN_TABLE Columns" for a description of the columns in the table.
While a PLAN_TABLE
table is automatically set up for each user, you can use the SQL script utlxplan.sql
to manually create a local PLAN_TABLE
in your schema. The exact name and location of this script depends on your operating system. On UNIX, it is located in the $ORACLE_HOME/rdbms/admin
directory.
For example, run the commands in Example 12-2 from a SQL*Plus session to create the PLAN_TABLE
in the HR
schema.
Example 12-2 Creating a PLAN_TABLE
CONNECT HR/your_password @$ORACLE_HOME/rdbms/admin/utlxplan.sql Table created.
Oracle recommends that you drop and rebuild your local PLAN_TABLE
table after upgrading the version of the database because the columns might change. This can cause scripts to fail or cause TKPROF
to fail, if you are specifying the table.
If you want an output table with a different name, first create PLAN_TABLE
manually with the utlxplan.sql
script and then rename the table with the RENAME
SQL statement. For example:
RENAME PLAN_TABLE TO my_plan_table;
12.3 Running EXPLAIN PLAN
To explain a SQL statement, use the EXPLAIN
PLAN
FOR
clause immediately before the statement. For example:
EXPLAIN PLAN FOR
SELECT last_name FROM employees;
12.4 Displaying PLAN_TABLE Output
Some examples of the use of DBMS_XPLAN
to display PLAN_TABLE
output are:
SELECT PLAN_TABLE_OUTPUT FROM TABLE(DBMS_XPLAN.DISPLAY());
SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY('MY_PLAN_TABLE', 'st1','TYPICAL'));
12.5 Reading EXPLAIN PLAN Output
This section uses EXPLAIN
PLAN
examples to illustrate execution plans. The statement in Example 12-5 is used to display the execution plans.
Example 12-5 Statement to display the EXPLAIN PLAN
SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'statement_id','BASIC'));
Examples of the output from this statement are shown in Example 12-6 and Example 12-7.
Example 12-6 EXPLAIN PLAN for Statement ID ex_plan1
EXPLAIN PLAN
SET statement_id = 'ex_plan1' FOR
SELECT phone_number FROM employees
WHERE phone_number LIKE '650%';
---------------------------------------
| Id | Operation | Name |
---------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | TABLE ACCESS FULL| EMPLOYEES |
---------------------------------------
This plan shows execution of a SELECT
statement. The table employees
is accessed using a full table scan.
Every row in the table employees
is accessed, and the WHERE
clause criteria is evaluated for every row.
The SELECT
statement returns the rows meeting the WHERE
clause criteria.
Example 12-7 EXPLAIN PLAN for Statement ID ex_plan2
EXPLAIN PLAN
SET statement_id = 'ex_plan2' FOR
SELECT last_name FROM employees
WHERE last_name LIKE 'Pe%';
SELECT PLAN_TABLE_OUTPUT
FROM TABLE(DBMS_XPLAN.DISPLAY(NULL, 'ex_plan2','BASIC'));
----------------------------------------
| Id | Operation | Name |
----------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | INDEX RANGE SCAN| EMP_NAME_IX |
----------------------------------------
This plan shows execution of a SELECT
statement.
Index EMP_NAME_IX
is used in a range scan operation to evaluate the WHERE
clause criteria.
The SELECT
statement returns rows satisfying the WHERE
clause conditions.