3. Indices virtuales
• El proceso de afinamiento de instrucciones SQL, requiere
que de manera alterna, podamos definir estrategias de
indexación, para observar su efecto en los planes de
ejecución.
• Crear índices adicionales, no es el problema.
4. Indices virtuales
• El problema es, que crear índices extras sobre tablas grandes, puede
tomar un monto considerado de tiempo y espacio en disco.
• Adicionalmente, los índices creados pueden ser utilizados por otras
sesiones de usuarios y podría afectar el rendimiento en otras partes de la
aplicación.
• Esto puede ser problemático cuando estamos intentando identificar el
problema en un sistema en producción.
5. Indices virtuales
– En contraste a los índices convencionales, los índices virtuales no
están asociados a un segmento, el tiempo de creación y el espacio
asociado en disco es irrelevante.
– Adicionalmente, no pueden ser vistos por otras sesiones, por tanto,
no se ve afectado el normal funcionamiento del sistema.
– Este clase muestra de manera sencilla como utilizarlos y las
consideraciones que debemos tener en cuenta.
6. Indices virtuales
SQL> desc movto_h
Name Null? Type
----------------------------------------- -------- --------------
NO_CIA NOT NULL VARCHAR2(2)
CENTRO NOT NULL VARCHAR2(2)
TIPO_DOC NOT NULL VARCHAR2(2)
PERIODO NOT NULL VARCHAR2(4)
RUTA NOT NULL VARCHAR2(4)
NO_DOCU NOT NULL VARCHAR2(12)
FECHA NOT NULL DATE
NO_FISICO VARCHAR2(12)
SERIE_FISICO VARCHAR2(15)
...
FECHA_APLICACION DATE
TSTAMP DATE
NO_TRASLADO VARCHAR2(12)
7. Indices virtuales
SQL> select count(*) from movto_h;
COUNT(*)
----------
6445961
8. Indices virtuales
SQL> create index v_movto_h_nofisico on movto_h(no_fisico) nosegment;
Index created.
SQL> explain plan for
2 select count(distinct no_fisico) from movto_h;
Explained.
9. Indices virtuales
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------
Plan hash value: 891170817
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 21381 (3)| 00:04:17 |
| 1 | SORT GROUP BY | | 1 | 7 | | |
| 2 | TABLE ACCESS FULL| movto_h | 6445K| 43M| 21381 (3)| 00:04:17 |
------------------------------------------------------------------------------
9 rows selected.
10. Indices virtuales
SQL> explain plan for
2 select count(distinct no_fisico) from movto_h where no_fisico < 10000;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
Plan hash value: 891170817
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 21547 (3)| 00:04:19 |
| 1 | SORT GROUP BY | | 1 | 7 | | |
|* 2 | TABLE ACCESS FULL| movto_h | 322K| 2203K| 21547 (3)| 00:04:19 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
11. Indices virtuales
SQL> create index v_movto_h_nofisico2 on
movto_h(to_number(no_fisico)) nosegment;
Index created.
SQL> explain plan for
2 select count(distinct no_fisico) from movto_h where no_fisico
< 10000;
Explained.
12. Indices virtuales
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------
Plan hash value: 891170817
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 21547 (3)| 00:04:19 |
| 1 | SORT GROUP BY | | 1 | 7 | | |
|* 2 | TABLE ACCESS FULL| movto_h | 322K| 2203K| 21547 (3)| 00:04:19 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------
2 - filter(TO_NUMBER("NO_FISICO")<10000)
14 rows selected.
13. Indices virtuales
SQL>
SQL> alter session set "_use_nosegment_indexes"=TRUE;
Session altered.
SQL> explain plan for
2 select count(distinct no_fisico) from movto_h where no_fisico <
10000;
Explained.
14. Indices virtuales
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------
Plan hash value: 2481667387
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 7 (0)| 00:00:01 |
| 1 | SORT GROUP BY | | 1 | 7 | | |
|* 2 | INDEX FAST FULL SCAN| V_movto_h_NOFISICO | 322K| 2203K| 7 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------
2 - filter(TO_NUMBER("NO_FISICO")<10000)
14 rows selected.
15. Indices virtuales
SQL> SELECT index_owner, index_name
2 FROM dba_ind_columns
3 WHERE index_name NOT LIKE 'BIN$%'
4 MINUS
5 SELECT owner, index_name
6 FROM dba_indexes;
INDEX_OWNER INDEX_NAME
------------------------------ ------------------------------
PRUEBAS21 V_movto_h_NOFISICO
PRUEBAS21 V_movto_h_NOFISICO2
PRUEBAS21 V_ARINMN
16. Indices virtuales
SQL> drop index v_movto_h_nofisico;
Index dropped.
SQL> explain plan for
2 select count(distinct no_fisico) from movto_h where no_fisico < 10000;
Explained.
17. Indices virtuales
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------
Plan hash value: 11771441
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 10 (0)| 00:00:01 |
| 1 | SORT GROUP BY | | 1 | 7 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| movto_h | 322K| 2203K| 10 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | V_movto_h_NOFISICO2 | 58014 | | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access(TO_NUMBER("NO_FISICO")<10000)
15 rows selected.
18. Indices virtuales
SQL> select count(*) from movto_h;
COUNT(*)
----------
6445961
drop index v_movto_h_nofisico2;
create index v_movto_h_nofisico2 on movto_h(to_number(no_fisico)) nosegment;
drop index v_movto_h_nofisico2;
create index v_movto_h_nofisico2 on movto_h(to_number(no_fisico));
SQL> drop index v_movto_h_nofisico2;
Index dropped.
19. Indices virtuales
SQL>
SQL> set timing on;
SQL>
SQL> create index v_movto_h_nofisico2 on movto_h(to_number(no_fisico))
nosegment;
Index created.
Elapsed: 00:00:00.03
SQL> drop index v_movto_h_nofisico2;
Index dropped.
Elapsed: 00:00:00.02
20. Indices virtuales
SQL> create index v_movto_h_nofisico2 on
movto_h(to_number(no_fisico));
Index created.
Elapsed: 00:01:09.56
SQL> explain plan for
2 select count(distinct no_fisico) from movto_h where no_fisico
< 10000;
Explained.
Elapsed: 00:00:00.01
21. Indices virtuales
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
Plan hash value: 891170817
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 21547 (3)| 00:04:19 |
| 1 | SORT GROUP BY | | 1 | 7 | | |
|* 2 | TABLE ACCESS FULL| movto_h | 322K| 2203K| 21547 (3)| 00:04:19 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------
2 - filter(TO_NUMBER("NO_FISICO")<10000)
14 rows selected.
22. Indices virtuales
SQL> alter session set "_use_nosegment_indexes"=FALSE;
Session altered.
Elapsed: 00:00:00.01
SQL> explain plan for
2 select count(distinct no_fisico) from movto_h where no_fisico < 10000;
Explained.
Elapsed: 00:00:00.01
SQL> select * from table(dbms_xplan.display);
23. Indices virtuales
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
Plan hash value: 891170817
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 21547 (3)| 00:04:19 |
| 1 | SORT GROUP BY | | 1 | 7 | | |
|* 2 | TABLE ACCESS FULL| movto_h | 322K| 2203K| 21547 (3)| 00:04:19 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------
2 - filter(TO_NUMBER("NO_FISICO")<10000)
14 rows selected.
25. Indices virtuales
Calculando estadísticas al índice virtual
SQL> drop index V_movto_h_NOFISICO2;
Index dropped.
SQL> create index v_movto_h_nofisico2 on
MOVTO_H(to_number(no_fisico)) nosegment;
Index created.
SQL> execute
dbms_stats.gather_index_stats('PRUEBAS21','V_MOVTO_H_NOFISICO2');
PL/SQL procedure successfully completed.
26. Indices virtuales
SQL> alter session set "_use_nosegment_indexes"=TRUE;
Session altered.
SQL> explain plan for
2 select count(distinct no_fisico) from MOVTO_H where no_fisico < 10000;
Explained.
SQL> set linesize 1000
SQL> select * from table(dbms_xplan.display);
27. Indices virtuales
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------
Plan hash value: 1788350122
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 30 (0)| 00:00:01 |
| 1 | SORT GROUP BY | | 1 | 7 | | |
| 2 | TABLE ACCESS BY INDEX ROWID| MOVTO_H | 218K| 1495K| 30 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | V_MOVTO_H_NOFISICO2 | 218K| | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access(TO_NUMBER("NO_FISICO")<10000)
28. Indices virtuales
El optimizador de Oracle 10g y superiores trabaja
basado en optimización por COSTO.
RBO no esta soportado en Oracle11g
29.
30. Columnas Virtuales
Columnas Virtuales
Fórmula / columnas calculadas - sobre la base de datos
Restricciones adicionales - sobre la base de datos
Nueva categoría para la partición - sobre la base de datos
Integridad creativa de referencia - en la base de datos
Sin columnas virtuales- inconvenientes
Triggers - caros
Vistas- a veces se olvidan
Re-diseño – Mucho trabajo duro!
31. Columnas Virtuales
SQL> show user
USER is "DEMO_LAB"
SQL> desc employees
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
SQL>
SQL>
32. Columnas Virtuales
1 insert into employees(employee_id, first_name, last_name, email, hire_date, job_id)
2* values (&empleado_id, '&nombre', '&apellido', '&email', to_date('&nacimiento','dd-mm-yyyy'),
&id_empleado)
SQL> /
Enter value for empleado_id: 1
Enter value for nombre: Ronald
Enter value for apellido: Vargas
Enter value for email: rvargas@laboratorio.com
Enter value for nacimiento: 03-09-1968
Enter value for id_empleado: 10
old 2: values (&empleado_id, '&nombre', '&apellido', '&email', to_date('&nacimiento','dd-mm-yyyy'),
&id_empleado)
new 2: values (1, 'Ronald', 'Vargas', 'rvargas@laboratorio.com', to_date('03-09-1968','dd-mm-yyyy'), 10)
1 row created.
SQL> commit;
38. Columnas Virtuales
SQL> alter table employees add email_sugerido as (substr(first_name,1,1)||'.'||
last_name||'@'||'laboratorio.com');
Table altered.
SQL> /
FIRST_NAME LAST_NAME SALARY IMPUESTO_RENTA EMAIL_SUGERIDO
-------------------- ------------------------- ---------- --------------
-----------------------------
Ronald Vargas 400000 40000 R.Vargas@laboratorio.com
SQL> update employees set first_name='Manuel' where
impuesto_renta=40000;
1 row updated.
SQL> commit;
Commit complete.
39. Columnas Virtuales
SQL> select first_name, last_name, salary, impuesto_renta, email_sugerido from
employees;
FIRST_NAME LAST_NAME SALARY IMPUESTO_RENTA EMAIL_SUGERIDO
-------------------- ------------------------- ---------- -------------- --------------------------
Manuel Vargas 400000 40000 M.Vargas@laboratorio.com
SQL> desc employees
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID NUMBER(6)
FIRST_NAME VARCHAR2(20)
LAST_NAME NOT NULL VARCHAR2(25)
EMAIL NOT NULL VARCHAR2(25)
PHONE_NUMBER VARCHAR2(20)
HIRE_DATE NOT NULL DATE
JOB_ID NOT NULL VARCHAR2(10)
SALARY NUMBER(8,2)
COMMISSION_PCT NUMBER(2,2)
MANAGER_ID NUMBER(6)
DEPARTMENT_ID NUMBER(4)
IMPUESTO_RENTA NUMBER
EMAIL_SUGERIDO VARCHAR2(41)
40.
41. Crear un dblink sin tocar el tnsnames
system@TEST11> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production
PL/SQL Release 11.1.0.7.0 - Production
CORE 11.1.0.7.0 Production
TNS for Linux: Version 11.1.0.7.0 - Production
NLSRTL Version 11.1.0.7.0 - Production
5 rows selected.
system@TEST11> select * from dba_db_links;
no rows selected
42. Crear un dblink sin tocar el tnsnames
system@TEST1
1> create database link testlink_db2
2 connect to system identified by oracle
3 using
4 '(DESCRIPTION=
5 (ADDRESS=
6 (PROTOCOL=TCP)
7 (HOST=10.2.10.18)
8 (PORT=1525))
9 (CONNECT_DATA=
10 (SID=test10)))'
11 /
Database link created.
43. Crear un dblink sin tocar el tnsnames
system@TEST11> select * from v$version@testlink_db2;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
5 rows selected.
-- cleanout
system@TEST11> drop database link testlink_db2;
Database link dropped.