Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Pgina 1 de 10
Este sitio emplea cookies como ayuda para prestar servicios. Al utilizar este sitio, ests aceptando el uso de cookies.
Datos
personales
Nombre:
Oracle DBA
Lugar: Spain
Ver todo mi perfil
Posts anteriores
Otro producto
cartesiano...
NOT IN vs. NOT
EXISTS.
Dlo de otra
forma.
Mala
Cardinalidad.
Links
Ask Tom
Oracle Base
Oracle TechNet
Metalink
BlogOracle
archives
octubre 2005
http://optimizacionsql.blogspot.com.es/
18/03/2015
Pgina 2 de 10
|
|
|
2 |
MERGE JOIN CARTESIAN
|
| 1448M|
58G|
16 |
|
|
|
3 |
NESTED LOOPS
|
|
971 | 35927 |
16 |
|
|
|
4 |
TABLE ACCESS BY INDEX ROWID
| LK_C_ESTADOS_BIT_03
|
1 |
20 |
1 |
|
|
|* 5 |
INDEX UNIQUE SCAN
| PK_C_ESTADOS_BIT_03
|
1 |
|
|
|
|
|* 6 |
INDEX RANGE SCAN
| IDX_FECHA_ESTADO_CONT_JAVIER |
971 | 16507 |
15 |
|
|
|
7 |
BUFFER SORT
|
| 1491K| 8739K|
1 |
|
|
|
8 |
INDEX FULL SCAN
| PK_C_CLIENTES_BIT_03
| 1491K| 8739K|
|
|
|
|* 9 |
TABLE ACCESS BY GLOBAL INDEX ROWID| BS_C_CONTRATOS_BIT_03
|
1 |
10 |
| ROWID |
ROW L |
|* 10 |
INDEX UNIQUE SCAN
| PK_C_CONTRATOS_BIT_03
|
1 |
|
|
|
|
-------------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------5 - access("HSCONTRATOS_ESTADOS"."ESTADO_ID"='BA')
6 - access("HS_C_ESTADOS_CONTRATO_BIT_03"."FEC_ESTADO_DT">=TO_DATE('2005-06-01 00:00:00', 'yyyy-mm-dd
hh24:mi:ss') AND "HS_C_ESTADOS_CONTRATO_BIT_03"."ESTADO_ID"='BA' AND
"HS_C_ESTADOS_CONTRATO_BIT_03"."FEC_ESTADO_DT"<=TO_DATE('2005-06-30 23:59:59', 'yyyy-mm-dd
hh24:mi:ss'))
filter("HS_C_ESTADOS_CONTRATO_BIT_03"."ESTADO_ID"="HSCONTRATOS_ESTADOS"."ESTADO_ID" AND
"HS_C_ESTADOS_CONTRATO_BIT_03"."ESTADO_ID"='BA')
9 - filter("BS_C_CLIENTES_BIT_03"."ABONADO_ID"="CONTRATOS"."ABONADO_ID")
10 - access("HS_C_ESTADOS_CONTRATO_BIT_03"."CONTRATO_ID"="CONTRATOS"."CONTRATO_ID")
Note: cpu costing is off
********************************************************************************
SOLUCIN al caso.
********************************************************************************
Las tablas contienen estadsticas fieles. El producto cartesiano tampoco
engaa: cruzar 58 Gb. para atender nuestra peticin. De todas maneras,
algo falla. Ese plan no es ptimo.
Las estadsticas
DBMS_STATS.
se
generan
mediante
la
siguiente
llamada
SQL> begin
2
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>usuario,
3
TABNAME=>tabla,
4
ESTIMATE_PERCENT=>dbms_stats.auto_sample_size,
5
METHOD_OPT => 'FOR ALL INDEXED COLUMNS SIZE 1',
6
DEGREE=>4);
7 end;
8 /
PL/SQL procedure successfully completed.
SQL> @c:\oracle\ora92\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes |
http://optimizacionsql.blogspot.com.es/
18/03/2015
Pgina 3 de 10
Cost |
----------------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
471 | 30615 |
405 |
|* 1 | HASH JOIN
|
|
471 | 30615 |
405 |
|* 2 |
INDEX RANGE SCAN
| IDX_FECHA_ESTADO_CONT_JAVIER | 8740 |
145K|
75 |
|
3 |
NESTED LOOPS
|
|
771K|
35M|
257 |
|
4 |
NESTED LOOPS
|
| 1626K|
46M|
257 |
|
5 |
TABLE ACCESS BY INDEX ROWID| LK_C_ESTADOS_BIT_03
|
1 |
20
|
1 |
|* 6 |
INDEX UNIQUE SCAN
| PK_C_ESTADOS_BIT_03
|
1 |
|
|
|
7 |
INDEX FAST FULL SCAN
| IDX_ABONADO_CONTRATO
| 1626K|
15M|
256 |
|
8 |
TABLE ACCESS BY INDEX ROWID | BS_C_CLIENTES_BIT_03
|
1 |
18
|
|
|* 9 |
INDEX UNIQUE SCAN
| PK_C_CLIENTES_BIT_03
|
1 |
|
|
----------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------1 - access("HS_C_ESTADOS_CONTRATO_BIT_03"."CONTRATO_ID"="CONTRATOS"."CONTRATO_ID" AND
"HS_C_ESTADOS_CONTRATO_BIT_03"."ESTADO_ID"="HSCONTRATOS_ESTADOS"."ESTADO_ID")
2 - access("HS_C_ESTADOS_CONTRATO_BIT_03"."FEC_ESTADO_DT">=TO_DATE('2005-06-01
00:00:00',
'yyyy-mm-dd hh24:mi:ss') AND "HS_C_ESTADOS_CONTRATO_BIT_03"."ESTADO_ID"='BA'
AND
"HS_C_ESTADOS_CONTRATO_BIT_03"."FEC_ESTADO_DT"<=TO_DATE('2005-06-30
23:59:59', 'yyyy-mm-dd
hh24:mi:ss'))
filter("HS_C_ESTADOS_CONTRATO_BIT_03"."ESTADO_ID"='BA')
6 - access("HSCONTRATOS_ESTADOS"."ESTADO_ID"='BA')
9 - access("BS_C_CLIENTES_BIT_03"."ABONADO_ID"="CONTRATOS"."ABONADO_ID")
Note: cpu costing is off
30 rows selected.
http://optimizacionsql.blogspot.com.es/
18/03/2015
Pgina 4 de 10
--------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes | Cost | Pstart| Pstop |
--------------------------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
1 |
44 | 3343 |
|
|
|
1 | SORT AGGREGATE
|
|
1 |
44 |
|
|
|
|* 2 |
FILTER
|
|
|
|
|
|
|
|* 3 |
FILTER
|
|
|
|
|
|
|
|* 4 |
HASH JOIN OUTER
|
|
|
|
|
|
|
|
5 |
TABLE ACCESS FULL
| TM_C_CLIENTES_SAC_02
| 74323 |
870K| 2407 |
|
|
|
6 |
TABLE ACCESS FULL
| TE_M_ERRORES_BIT_01
|
1 |
32 |
2 |
13 |
13 |
|
7 |
NESTED LOOPS
|
| 1640K|
50M|
922 |
|
|
|
8 |
PARTITION LIST ALL
|
|
|
|
|
1 |
7 |
|
9 |
TABLE ACCESS FULL
| BS_C_CONTRATOS_BIT_03 | 1640K|
20M|
922 |
1 |
7 |
|* 10 |
TABLE ACCESS BY INDEX ROWID| BS_C_CUENTAS_BIT_03
|
1 |
19 |
|
|
|
|* 11 |
INDEX UNIQUE SCAN
| PK_C_CUENTAS_BIT_03
|
1 |
|
|
|
|
--------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------2 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "BITOWN03"."BS_C_CUENTAS_BIT_03"
"CU","BITOWN03"."BS_C_CONTRATOS_BIT_03" "CONT" WHERE "CU"."CUENTA_ID"="CONT"."CUENTA_ID" AND
LNNVL("CU"."ABONADO_ID"<>:B1)))
3 - filter("TE_M_ERRORES_BIT_01"."ERROR_ID" IS NULL)
4 - access("SYS_ALIAS_1".ROWID="TE_M_ERRORES_BIT_01"."FILA_ID"(+))
10 - filter(LNNVL("CU"."ABONADO_ID"<>:B1))
11 - access("CU"."CUENTA_ID"="CONT"."CUENTA_ID")
Note: cpu costing is off
30 rows selected.
********************************************************************************
SOLUCIN al caso.
********************************************************************************
En este caso, la consulta con IN tiene un coste aceptable. No obstante,
despus de cinco horas de ejecucin, es de sospechar que la cosa no va
muy bien. La estrategia de ejecucin es realizar dos FILTER: el primero
para el OuterJoin de Clientes sin errores y el segundo para combinarlo (en
un pesadsimo NestedLoops) con las cuentas con contratos.
Como la subconsulta est resultando ms pesada incluso que la principal,
es posible que sustituir IN por la clusula EXISTS sea una buena
estrategia.
S, tambin tengo cuidado que no haya cdigos con valor NULL para
resolver la consulta, ya que NOT IN y NOT EXISTS no son lo mismo.
Sustituyo NOT IN por NOT EXISTS y la consulta queda de este modo:
SQL> @c:\oracle\ora92\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
| Rows | Bytes |TempSpc| Cost | Pstart|
Pstop |
http://optimizacionsql.blogspot.com.es/
18/03/2015
Pgina 5 de 10
------------------------------------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
1 |
57 |
| 4946
|
|
|
|
1 | SORT AGGREGATE
|
|
1 |
57 |
|
|
|
|
|* 2 |
FILTER
|
|
|
|
|
|
|
|
|* 3 |
HASH JOIN OUTER
|
|
|
|
|
|
|
|
|* 4 |
HASH JOIN ANTI
|
| 1486K|
35M|
34M| 4269
|
|
|
|
5 |
TABLE ACCESS FULL
| TM_C_CLIENTES_SAC_02
| 1486K|
17M|
| 2407
|
|
|
|
6 |
VIEW
| VW_SQ_1
| 1640K|
20M|
|
922
|
|
|
|
7 |
NESTED LOOPS
|
| 1640K|
50M|
|
922
|
|
|
|
8 |
PARTITION LIST ALL
|
|
|
|
|
| 1
|
7 |
|
9 |
TABLE ACCESS FULL
| BS_C_CONTRATOS_BIT_03 | 1640K|
20M|
|
922 | 1
|
7 |
| 10 |
TABLE ACCESS BY INDEX ROWID| BS_C_CUENTAS_BIT_03
|
1 |
19 |
|
|
|
|
|* 11 |
INDEX UNIQUE SCAN
| PK_C_CUENTAS_BIT_03
|
1 |
|
|
|
|
|
| 12 |
TABLE ACCESS FULL
| TE_M_ERRORES_BIT_01
|
1 |
32 |
|
2 | 13
|
13 |
------------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------2
3
4
11
filter("TE_M_ERRORES_BIT_01"."ERROR_ID" IS NULL)
access("CLI".ROWID="TE_M_ERRORES_BIT_01"."FILA_ID"(+))
access("CLI"."COD_ABONADO"="VW_SQ_1"."ABONADO_ID")
access("CU"."CUENTA_ID"="CONT"."CUENTA_ID")
http://optimizacionsql.blogspot.com.es/
18/03/2015
Pgina 6 de 10
|
5 |
BUFFER
SORT
|
| 4510K|
25M|
|
|
6 |
INDEX FULL SCAN
|
PK_R_NODOS_BIT_03
| 4510K|
25M|
|
|* 7 |
INDEX RANGE SCAN
| IDX_NODO_CONEX_EXTERNA
|
1
|
12 |
|
---------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------7 - access("B"."NODO_B_ID"="C"."NODO_ID" AND
"A"."NODO_ID"="B"."NODO_A_ID")
Note: cpu costing is off
********************************************************************************
SOLUCIN al caso.
********************************************************************************
Otro producto cartesiano. En este caso el cartesiano sabe muy bien lo que
hace. Cruza casi 6.000 millones de filas (en total 61 gigas de informacin)
y un coste mnimo. Vaya paradoja.
Un detalle para entender esta decisin: no existen restricciones de Primary
Key, ni
Foreign Key, ni ndices nicos, ni restricciones de Not Null.
A causa de ello, Oracle encuentra prctico combinar todos los resultados
de una tabla (4,5 millones) sobre las 1400 filas de la otra tabla, en un
"todos con todos".
No est mal. No obstante, hay informacin que Oracle, por mucho que
analice las tablas, no va a poder obtener a priori. nicamente nos
interesan valores nicos de la tabla de relacin, que existan en sus
respectivas tablas relacionadas, pero, como digo, no existe nada que aporte
a Oracle esa informacin.
Cambio algunos detalles de la consulta y la dejo as:
Informo de dos cosas: que tengo inters en obtener los cdigos distintos de
la tabla de relacin, y que adems existan en las otras dos tablas.
El plan de ejecucin cambia totalmente para ejecutarse tal como lo he
dicho de otra forma. Ahora Oracle realiza este otro plan de ejecucin.
SQL> @c:\oracle\ora92\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
http://optimizacionsql.blogspot.com.es/
18/03/2015
Pgina 7 de 10
----------------------| Id | Operation
| Name
| Rows |
Bytes |TempSpc| Cost |
-------------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
| 5554
|
200K|
| 13626 |
|
1 | NESTED LOOPS
|
| 5554
|
200K|
| 13626 |
|
2 |
NESTED LOOPS
|
| 5554
|
168K|
| 13626 |
|
3 |
VIEW
|
| 7159K|
177M|
| 13626 |
|
4 |
SORT UNIQUE
|
| 7159K|
81M|
273M| 13626 |
|
5 |
TABLE ACCESS FULL|
RE_R_CONEX_EXTERNAS_BIT_03 | 7159K|
81M|
| 2589 |
|* 6 |
INDEX UNIQUE SCAN | PK_TMP_MANEL_03
|
1
|
5 |
|
|
|* 7 |
INDEX UNIQUE SCAN
| PK_R_NODOS_BIT_03
|
1
|
6 |
|
|
-------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------6 - access("B"."NODO_B_ID"="C"."NODO_ID")
7 - access("A"."NODO_ID"="B"."NODO_A_ID")
Mala Cardinalidad.
Para Cristina lvarez, quien confi en mi desde el primer momento y
lo disimul con toda su alma. :)
La siguiente consulta ha sido cancelada tras una hora y veinte
minutos de ejecucin.
SELECT N2.ENTIDAD_ID,
CLI.rowid row_id, cli.*,
MAX(REL.ABONADO_PADRE_ID) OVER (PARTITION BY
ABONADO_HIJO_ID) REL_ABONADO_PADRE_ID
FROM BITOWN03.BS_V_MGEC_NODO_BIT_03 N1,
BITOWN03.BS_V_MGEC_NODO_BIT_03 N2,
BITOWN03.BS_V_MGEC_REL_NODOS_BIT_03 RN,
BITOWN02.TM_C_CLIENTES_SAC_02 CLI,
BITOWN03.RE_C_RELACIONES_ABONADO_BIT_03 REL
WHERE N1.ENTIDAD_ID= CLI.COD_DNICIF
AND N1.NODO_ID=RN.NODO_ID
AND RN.TIPO_RELACION_ID=2 AND RN.FECHA_FIN_DT IS NULL
AND RN.NODO_PADRE_ID=N2.NODO_ID
AND CLI.COD_ABONADO = REL.ABONADO_HIJO_ID (+);
http://optimizacionsql.blogspot.com.es/
18/03/2015
Pgina 8 de 10
********************************************************************************
SOLUCIN al caso.
********************************************************************************
Omitiendo el detalle que la clusula distinct sobra. La mantenemos para
que los planes resulten de ejecuciones similares.
Parece un plan bastante aceptable. No obstante, un producto cartesiano
llama la atencin... nicamente se obtiene una fila? en ese caso, el
cartesiano no hace dao. Vamos a consultar el total de filas de la tabla, si la
tabla tiene generadas estadsticas (la columna num_rows de user_tables
http://optimizacionsql.blogspot.com.es/
18/03/2015
Pgina 9 de 10
SQL> @c:\oracle\ora92\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation
| Name
|
Rows | Bytes |TempSpc| Cost |
-------------------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
209K|
53M|
| 12462 |
http://optimizacionsql.blogspot.com.es/
18/03/2015
Pgina 10 de 10
|
1 | SORT UNIQUE
|
|
209K|
53M|
112M| 12462 |
|
2 |
WINDOW SORT
|
|
209K|
53M|
112M| 12462 |
|
3 |
NESTED LOOPS OUTER
|
|
209K|
53M|
| 4217 |
|* 4 |
HASH JOIN
|
|
209K|
51M|
| 4217 |
|* 5 |
HASH JOIN
|
|
12841 |
589K|
|
320 |
|* 6 |
HASH JOIN
|
|
12841 |
388K|
|
192 |
|* 7 |
TABLE ACCESS FULL| BS_V_MGEC_REL_NODOS_BIT_03
|
12841 |
188K|
|
70 |
|
8 |
TABLE ACCESS FULL| BS_V_MGEC_NODO_BIT_03
|
128K| 2012K|
|
112 |
|
9 |
TABLE ACCESS FULL | BS_V_MGEC_NODO_BIT_03
|
128K| 2012K|
|
112 |
| 10 |
TABLE ACCESS FULL |
TM_C_CLIENTES_SAC_02
| 1486K|
297M|
| 2407 |
|* 11 |
INDEX FULL SCAN
|
PK_C_RELACIONES_ABONADO_BIT_03 |
1 |
12 |
|
|
-------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------4 5 6 7 NULL)
11 -
access("N1"."ENTIDAD_ID"="CLI"."COD_DNICIF")
access("RN"."NODO_PADRE_ID"="N2"."NODO_ID")
access("N1"."NODO_ID"="RN"."NODO_ID")
filter("RN"."TIPO_RELACION_ID"=2 AND "RN"."FECHA_FIN_DT" IS
access("CLI"."COD_ABONADO"="REL"."ABONADO_HIJO_ID"(+))
filter("CLI"."COD_ABONADO"="REL"."ABONADO_HIJO_ID"(+))
http://optimizacionsql.blogspot.com.es/
18/03/2015