Can't parallelize creation of a Materiazed View - oracle

I',m tryng to create a Materialized View referencing a remote table with over 8 million records.
I put the clausole "PARALLEL 8" in DDL MVIEW statement and the hint "/*+ PARALLEL(8) */ in the MVIEW QUERY.
When creating, no parallel slave process was activated for the process.
What's the matter ?
Thanks in advice.
These are DOP parameter of the target server:
NAME TYPE VALUE
------------------------------------ ----------- -----------------------
fast_start_parallel_rollback string LOW
parallel_adaptive_multi_user boolean TRUE
parallel_automatic_tuning boolean FALSE
parallel_degree_level integer 100
parallel_degree_limit string CPU
parallel_degree_policy string MANUAL
parallel_execution_message_size integer 16384
parallel_force_local boolean FALSE
parallel_instance_group string
parallel_io_cap_enabled boolean FALSE
parallel_max_servers integer 80
parallel_min_percent integer 0
parallel_min_servers integer 8
parallel_min_time_threshold string AUTO
parallel_server boolean FALSE
parallel_server_instances integer 1
parallel_servers_target integer 32
parallel_threads_per_cpu integer 2
recovery_parallelism integer 0
I tried setting the parameter "parallel_degree_policy" from MANUAL to AUTO, and altering session (before launching the MVIEW creation statement") with:
ALTER SESSION FORCE PARALLEL DML PARALLEL 8;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 8;
...but with the same result..
Here's the MVIEW DDL:
CREATE MATERIALIZED VIEW NEMESI_REPLICA.SCGC_CONSENSI (ID_CODICE_CONSENSO,ID_CLIENTE,OPERATORE,TIMESTAMP_SCGC,TIMESTAMP_CONSENSO,ARCHIVIAZIONE,VALORE_CONSENSO,ID_SISTEMA,ID_SOCIETA,ID_CANALE_ACQUISIZIONE,INTEGRITA,NOTA,ID_IDENTIFICAZIONE_CLIENTE,CANALE_SCGC,STATO_CLIENTE,ID_FRONTEND)
TABLESPACE TBS_NEMESI_REPLICA
PCTUSED 0
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 1M
NEXT 30M
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
)
NOCACHE
NOLOGGING
NOCOMPRESS
PARALLEL 8
BUILD IMMEDIATE
USING INDEX
TABLESPACE TBS_NEMESI_REPLICA
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 1M
NEXT 50M
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
REFRESH FAST ON DEMAND
WITH PRIMARY KEY
AS
SELECT
/*+ PARALLEL(8) */
"SCGC_CONSENSI"."ID_CODICE_CONSENSO" "ID_CODICE_CONSENSO",
"SCGC_CONSENSI"."ID_CLIENTE" "ID_CLIENTE",
"SCGC_CONSENSI"."OPERATORE" "OPERATORE",
"SCGC_CONSENSI"."TIMESTAMP_SCGC" "TIMESTAMP_SCGC",
"SCGC_CONSENSI"."TIMESTAMP_CONSENSO" "TIMESTAMP_CONSENSO",
"SCGC_CONSENSI"."ARCHIVIAZIONE" "ARCHIVIAZIONE",
"SCGC_CONSENSI"."VALORE_CONSENSO" "VALORE_CONSENSO",
"SCGC_CONSENSI"."ID_SISTEMA" "ID_SISTEMA",
"SCGC_CONSENSI"."ID_SOCIETA" "ID_SOCIETA",
"SCGC_CONSENSI"."ID_CANALE_ACQUISIZIONE" "ID_CANALE_ACQUISIZIONE",
"SCGC_CONSENSI"."INTEGRITA" "INTEGRITA",
"SCGC_CONSENSI"."NOTA" "NOTA",
"SCGC_CONSENSI"."ID_IDENTIFICAZIONE_CLIENTE"
"ID_IDENTIFICAZIONE_CLIENTE",
"SCGC_CONSENSI"."CANALE_SCGC" "CANALE_SCGC",
"SCGC_CONSENSI"."STATO_CLIENTE" "STATO_CLIENTE",
"SCGC_CONSENSI"."ID_FRONTEND" "ID_FRONTEND"
FROM
"SCGC_ONLINE"."SCGC_CONSENSI"#"NEMESI_LINK" "SCGC_CONSENSI";

You put the parallel on mview DDL and on mview query, maybe you hitting some bug
Parallel DML Not Used For Mview Refresh (Doc ID 2529168.1)
Check the MOS notes, and do some solutions.
Other approach is to alter the master table do degree>1, and then your refresh will be in parallel.
"When the master table of the materialized view has the PARALLEL attribute set to > 1, then the
creation as well as the refresh processes will be parallelized. Whether or not you specify the
PARALLELISM parameter in the REFRESH clause, doesn't matter."
How to Refresh a Materialized View in Parallel (Doc ID 577870.1)
I would first, trying the second approach, and alter the degree of your master table to do a test. If not resolve your issue, check the MOS note

Related

Oracle update throws timeout

I am having a very simple oracle update:
update inv_li_pck_inst set mig_li_pck_inst_id = 9377 where id = 9384
Both records exist in the table inv_li_pck_inst: id=9377 and id=9384
Record with id=9377 is migration record.
Problem is that this very simple update query takes ages to run - and at the end throws timeout exception. What could possibly be wrong here? IDs in the table inv_li_pck_inst are unique.
Table DDL:
CREATE TABLE "TESTING_INV"."INV_LI_PCK_INST"
( "ID" NUMBER NOT NULL ENABLE,
"LI_PCK_ID" NUMBER NOT NULL ENABLE,
"WORKFLOW_ID" NUMBER,
"INSERTED" DATE NOT NULL ENABLE,
"INSERTED_BY" NUMBER(9,0) NOT NULL ENABLE,
"UPDATED" DATE,
"UPDATED_BY" NUMBER(9,0),
"DELETED" DATE,
"DELETED_BY" NUMBER(9,0),
"MIG_LI_PCK_INST_ID" NUMBER,
"STATUS_ID" NUMBER,
"WFI_ID" NUMBER,
"TOF_WFI_ID" NUMBER,
CONSTRAINT "PK_INV_LI_PCK_INST" PRIMARY KEY ("ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TESTING_INV_DATA" ENABLE,
CONSTRAINT "FK_LPI_WORKFLOW" FOREIGN KEY ("WORKFLOW_ID")
REFERENCES "TESTING_INV"."WORKFLOW" ("WORKFLOW_ID") ENABLE,
CONSTRAINT "FK_LIPI_STATUS" FOREIGN KEY ("STATUS_ID")
REFERENCES "TESTING_INV"."INV_LI_PCK_INST_STATUS" ("ID") ENABLE,
CONSTRAINT "FK_LIPI_MIG_PCK_INST" FOREIGN KEY ("MIG_LI_PCK_INST_ID")
REFERENCES "TESTING_INV"."INV_LI_PCK_INST" ("ID") ENABLE,
CONSTRAINT "FK_LI_PCK_INST_WFI" FOREIGN KEY ("WFI_ID")
REFERENCES "TESTING_INV"."WFI" ("WFI_ID") ENABLE,
CONSTRAINT "FK_INV_LI_PCK_INST5" FOREIGN KEY ("TOF_WFI_ID")
REFERENCES "TESTING_INV"."WFI" ("WFI_ID") ENABLE,
CONSTRAINT "FK_LPI_LI_PCK" FOREIGN KEY ("LI_PCK_ID")
REFERENCES "TESTING_INV"."INV_LI_PCK" ("ID") ENABLE
) SEGMENT CREATION IMMEDIATE
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TESTING_INV_DATA" ;
CREATE INDEX "TESTING_INV"."IDX_LI_PCK_INST_WFI" ON "TESTING_INV"."INV_LI_PCK_INST" ("WFI_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TESTING_INV_DATA" ;
CREATE UNIQUE INDEX "TESTING_INV"."UN_LI_PCK_INST" ON "TESTING_INV"."INV_LI_PCK_INST" (NVL2("DELETED","ID",NULL), "WORKFLOW_ID")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TESTING_INV_DATA" ;
CREATE OR REPLACE EDITIONABLE TRIGGER "TESTING_INV"."TRG_INV_LI_PCK_INST"
before insert on INV_LI_PCK_INST
for each row
begin
select SEQ_INV_LI_PCK_INST.nextval into :new.ID from dual;
end;
/
ALTER TRIGGER "TESTING_INV"."TRG_INV_LI_PCK_INST" ENABLE;
Most probable scenario is that there is an other migration session (or more of them) and it blocks your session.
Simple setup
create table testing
(ID NUMBER primary key,
MIG_ID NUMBER );
alter table testing add (
constraint mig foreign key(MIG_ID) references testing(id));
insert into testing (id, mig_id) values(9384, null);
insert into testing (id, mig_id) values(9377, null);
commit;
If you now performs the UPDATE is goes perfectly smooth:
update testing set mig_id = 9377 where id = 9384;
But if you before the update performs a delete of the migrated ID form an other session and do not commit it, your update will "hang" forever.
-- perform from other session and do not commit
delete from testing where id = 9377;
Why, because if the update would be done and the delete session would be commited - the referential integrity will be violeted. The UPDATE must wait until the deleted is commited or rollbacked to see if the reference ID is there or not.
How to dignose?
Simple check the v$session (or GV of RAC) and see the blocking_status and event
select SID, SERIAL#,STATUS,SQL_ID, BLOCKING_SESSION_STATUS, BLOCKING_SESSION,EVENT
from v$session
where USERNAME = your_user
You will see (most probably) your session with BLOCKING_SESSION_STATUS = VALID and
EVENT = enq: TX - row lock contention. In BLOCKING_SESSION you can find the session ID of your interacting session.
The SQL_ID will tell you what the other session is doing.

Get complete ddl for index in oracle

I am using oracle 11g/12c. I want to get ddl of indexes in my database. For this I used the query -
SELECT DBMS_METADATA.GET_DDL('INDEX','SYS_IL0000091971C00001$$','CCEEXPERTS') FROM dual
Here 'SYS_IL0000091971C00001$$' is my index name and 'CCEEXPERTS' is my owner name.
From this I get the ddl -
CREATE UNIQUE INDEX "CCEEXPERTS"."SYS_IL0000091971C00001$$" ON "CCEEXPERTS"."DATABLOB" (
And my actual ddl is -
CREATE UNIQUE INDEX "CCEEXPERTS"."SYS_IL0000091971C00001$$" ON "CCEEXPERTS"."DATABLOB" (
PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "USERS"
PARALLEL (DEGREE 0 INSTANCES 0) ;
In actual ddl after "CCEEXPERTS"."DATABLOB" ( , next line character and from their the ddl is truncted.
How can I get the complete ddl? Please help me...
Thanks in advance.
In SQLplus, set these before running the procedure.
set long 100000
set longchunksize 100000
Oracle has a DBMS_METADATA package to retrieve and customize the DDL returned. Default settings for all indexes SQL:
select DBMS_METADATA.GET_DDL('INDEX', index_name)
from all_indexes
where owner in (USER, 'USER_OTHER_THAN_LOGGED_IN_USER');
A pl/sql block example:
set serveroutput on
DECLARE
V_DDL CLOB;
BEGIN
DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',false);
DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'PRETTY', true);
dbms_metadata.set_transform_param(dbms_metadata.session_transform,'TABLESPACE',false);
V_DDL := DBMS_METADATA.GET_DDL('VIEW', 'A_VIEW_NAME');
DBMS_OUTPUT.PUT_LINE(V_DDL);
END;

Toad for Oracle, Editing ID Column to be an auto-increment ID

I work with Toad for Oracle 12.1 for my database. I have a Table called TBLEMPLOYEE which already contain some data in it and having Column Name called ID whose data values are increasing from 1 to N.
ID Name Gender DateOfBirth Type
------------------------------------
1 Mark Male 10/10/1982 1
2 Mary Female 11/11/1981 2
3 Esther Female 12/12/1984 2
4 Matthew Male 9/9/1983 1
5 John Male 5/5/1985 1
6 Luke Male 6/6/1986 1
Now I want to change the Column ID such that it will have auto-incremented ID when I add a new data to the Table.
I know that in Toad we can do it when we create a New Table with that behavior. For instance, using Create Table and in the newly created Column, we could set Default / Virtual / Identity settings as Identity:
And Toad will show a UI with bunch of settings to do that:
And will be automatically translated to something like:
(START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 9999999999999999999999999999 CACHE 20 NOCYCLE ORDER NOKEEP)
In the Default / Virtual / Identity settings.
But I can't seem to do the same when I do Alter Table instead of Create Table.
Why is that so?
And since I already have some data in the TBLEMPLOYEE, I want to avoid creating a new table and re-inserting the data if possible.
How can I do that?
This is the current SQL script (if this may help):
ALTER TABLE MYSCHEMA.TBLEMPLOYEE
DROP PRIMARY KEY CASCADE;
DROP TABLE MYSCHEMA.TBLEMPLOYEE CASCADE CONSTRAINTS;
CREATE TABLE MYSCHEMA.TBLEMPLOYEE
(
ID NUMBER NOT NULL,
NAME VARCHAR2(80 BYTE) NOT NULL,
GENDER VARCHAR2(6 BYTE),
DATEOFBIRTH DATE,
EMPLOYEETYPE INTEGER NOT NULL,
)
TABLESPACE USERS
RESULT_CACHE (MODE DEFAULT)
PCTUSED 0
PCTFREE 10
INITRANS 1
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
ALTER TABLE MYSCHEMA.TBLEMPLOYEE ADD (
PRIMARY KEY
(ID)
USING INDEX
TABLESPACE USERS
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
ENABLE VALIDATE);
First of all, your sequence should start with the max value + 1 from the table e.g.
(START WITH 7 INCREMENT BY 1 MINVALUE 1 MAXVALUE 9999999999999999999999999999 CACHE 20 NOCYCLE ORDER NOKEEP)
If you want to automatically populate the value for the Id and you're not running on Oracle 12c, I suggest you to use a trigger
drop sequence seq_mytest_id;
truncate table my_test_t;
drop table my_test_t;
create table my_test_t (id number, string varchar2(30));
-- prepopulate with fixed values for the id
insert into my_test_t(id, string) values (1,'test');
insert into my_test_t(id, string) values (2,'test');
insert into my_test_t(id, string) values (3,'test');
insert into my_test_t(id, string) values (4,'test');
insert into my_test_t(id, string) values (5,'test');
insert into my_test_t(id, string) values (6,'test');
commit;
--Now create the sequence and the trigger for automatically
--populating the ID column
create sequence seq_mytest_id start with 7 increment by 1 nocycle nocache;
create trigger t_mytest_bi before insert on my_test_t for each row
begin
select seq_mytest_id.nextval into :new.id from dual;
end;
/
-- Test the trigger
insert into my_test_t(string) values ('test');
insert into my_test_t(string) values ('test2');
commit;
select * from my_test_t;
If you're running on Oracle 12c you can define your column as an identity column
https://oracle-base.com/articles/12c/identity-columns-in-oracle-12cr1
Hope it helps,
R

Oracle: very slow query example. How to speed it up by looking at session browser?

I'm going to detail in every aspect a query which is really slow. Can you give me some advice to understand what should I consider to speed it up?
It involves just two tables.
SELECT /*+ leading(tb) */![enter image description here][1]
DISTINCT COUNT (huB.FLH_ID_MESSAGGIO), hub.flh_STATO, TB.LOTTO
FROM ENI_FLUSSI_HUB HUB, NETATEMP.TMP_GAB_RECOVERY_SCARTI tb
WHERE HUB.FLH_ID_MESSAGGIO = tb.FLH_ID_MESSAGGIO
AND hub.FLH_TIPO_PROCESSO_COD = tb.FLH_TIPO_PROCESSO_COD
AND TB.LOTTO IN (:"SYS_B_0", :"SYS_B_1", :"SYS_B_2", :"SYS_B_3")
AND HUB.FLH_FLAG_ANN = :"SYS_B_4"
GROUP BY hub.flh_STATO, TB.LOTTO
ORDER BY HUB.FLH_STATO
The first index script:
CREATE INDEX NETATEMP.ENI_ETAI_IDX2 ON NETATEMP.TMP_GAB_RECOVERY_SCARTI
(LOTTO, OPERATORE)
NOLOGGING
TABLESPACE NETATEMP_IDXTI
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 64K
NEXT 1M
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
NOPARALLEL;

Perfomance issues just on production database

I'm having some performance issues when querying a table in a production database. While the query runs in 2.1 seconds in the test database (returning 8640 of 28 million records), at production, it takes 2.05 minutes (returning 8640 of 31 million records). I'm having a hard time to find the problem since I'm not an oracle expert.
Since the explain plan in both databases shows the correct index usage, I'm inclined to think that the problem resides on the table/indexes creation.
I've noticed some small differences between the SQL scripts used for the table creation:
Test database:
create table TB_PONTO_ENE
(
cd_ponto NUMBER(10) not null,
cd_fonte NUMBER(10),
cd_medidor NUMBER(10),
cd_usuario NUMBER(10),
dt_hr_insercao DATE,
dt_hr_instante DATE not null,
dt_hr_hora DATE,
dt_hr_dia DATE,
dt_hr_mes DATE,
dt_hr_instante_hv DATE,
dt_hr_hora_hv DATE,
dt_hr_dia_hv DATE,
dt_hr_mes_hv DATE,
vl_eneat_del FLOAT,
vl_eneat_rec FLOAT,
vl_enere_del FLOAT,
vl_enere_rec FLOAT,
vl_eneat_del_cp FLOAT,
vl_eneat_rec_cp FLOAT,
vl_enere_del_cp FLOAT,
vl_enere_rec_cp FLOAT
)
tablespace TELEMEDICAO
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
alter table TB_PONTO_ENE
add constraint CP_TB_PONTO_ENE primary key (CD_PONTO, DT_HR_INSTANTE)
using index
tablespace TELEMEDICAO
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
alter table TB_PONTO_ENE
add constraint CE_PENE_CD_FONTE foreign key (CD_FONTE)
references TB_FONTE (CD_FONTE) on delete set null;
alter table TB_PONTO_ENE
add constraint CE_PENE_CD_MEDIDOR foreign key (CD_MEDIDOR)
references TB_MEDIDOR (CD_MEDIDOR) on delete set null;
alter table TB_PONTO_ENE
add constraint CE_PENE_CD_PONTO foreign key (CD_PONTO)
references TB_PONTO (CD_PONTO) on delete cascade;
alter table TB_PONTO_ENE
add constraint CE_PENE_CD_USUARIO foreign key (CD_USUARIO)
references TB_USUARIO (CD_USUARIO) on delete set null
disable;
Production database:
create table TB_PONTO_ENE
(
cd_ponto NUMBER(10) not null,
cd_fonte NUMBER(10),
cd_medidor NUMBER(10),
cd_usuario NUMBER(10),
dt_hr_insercao DATE,
dt_hr_instante DATE not null,
dt_hr_hora DATE,
dt_hr_dia DATE,
dt_hr_mes DATE,
dt_hr_instante_hv DATE,
dt_hr_hora_hv DATE,
dt_hr_dia_hv DATE,
dt_hr_mes_hv DATE,
vl_eneat_del FLOAT,
vl_eneat_rec FLOAT,
vl_enere_del FLOAT,
vl_enere_rec FLOAT,
vl_eneat_del_cp FLOAT,
vl_eneat_rec_cp FLOAT,
vl_enere_del_cp FLOAT,
vl_enere_rec_cp FLOAT
)
tablespace TELEMEDICAO
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
next 5M
minextents 1
maxextents unlimited
pctincrease 0
);
alter table TB_PONTO_ENE
add constraint CP_TB_PONTO_ENE primary key (CD_PONTO, DT_HR_INSTANTE)
using index
tablespace MEDICAO_NDX
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
next 1M
minextents 1
maxextents unlimited
pctincrease 0
);
alter table TB_PONTO_ENE
add constraint CE_PENE_CD_FONTE foreign key (CD_FONTE)
references TB_FONTE (CD_FONTE) on delete set null;
alter table TB_PONTO_ENE
add constraint CE_PENE_CD_MEDIDOR foreign key (CD_MEDIDOR)
references TB_MEDIDOR (CD_MEDIDOR) on delete set null;
alter table TB_PONTO_ENE
add constraint CE_PENE_CD_PONTO foreign key (CD_PONTO)
references TB_PONTO (CD_PONTO) on delete cascade;
alter table TB_PONTO_ENE
add constraint CE_PENE_CD_USUARIO foreign key (CD_USUARIO)
references TB_USUARIO (CD_USUARIO) on delete set null;
The production database puts the indexes in another tablespace. Another difference is the next 5M at the tablespace declaration (no value defined in the test database).
When looking at the index properties, I also see some differences:
Test database:
AVG_DATA_BLOCKS_PER_KEY 1
AVG_LEAF_BLOCKS_PER_KEY 1
BLEVEL 2
BUFFER_POOL DEFAULT
CLUSTERING_FACTOR 611494
COMPRESSION DISABLED
DEGREE 1
DISTINCT_KEYS 28568389
DROPPED NO
GENERATED N
GLOBAL_STATS YES
INDEX_NAME CP_TB_PONTO_ENE
INDEX_TYPE NORMAL
INITIAL_EXTENT 65536
INI_TRANS 2
INSTANCES 1
IOT_REDUNDANT_PKEY_ELIM NO
JOIN_INDEX NO
LAST_ANALYZED 21/07/2010 22:08:34
LEAF_BLOCKS 85809
LOGGING YES
MAX_EXTENTS 2147483645
MAX_TRANS 255
MIN_EXTENTS 1
NUM_ROWS 28568389
PARTITIONED NO
PCT_FREE 10
SAMPLE_SIZE 377209
SECONDARY N
STATUS VALID
TABLESPACE_NAME TELEMEDICAO
TABLE_NAME TB_PONTO_ENE
TABLE_TYPE TABLE
TEMPORARY N
UNIQUENESS UNIQUE
USER_STATS NO
Production database:
AVG_DATA_BLOCKS_PER_KEY 1
AVG_LEAF_BLOCKS_PER_KEY 1
BLEVEL 2
BUFFER_POOL DEFAULT
CLUSTERING_FACTOR 10154395
COMPRESSION DISABLED
DEGREE 1
DISTINCT_KEYS 14004395
GENERATED N
GLOBAL_STATS YES
INDEX_NAME CP_TB_PONTO_ENE
INDEX_TYPE NORMAL
INITIAL_EXTENT 65536
INI_TRANS 2
INSTANCES 1
JOIN_INDEX NO
LAST_ANALYZED 05/03/2010 08:45:19
LEAF_BLOCKS 42865
LOGGING YES
MAX_EXTENTS 2147483645
MAX_TRANS 255
MIN_EXTENTS 1
NEXT_EXTENT 1048576
NUM_ROWS 14004395
PARTITIONED NO
PCT_FREE 10
PCT_INCREASE 0
SAMPLE_SIZE 2800879
SECONDARY N
STATUS VALID
TABLESPACE_NAME MEDICAO_NDX
TABLE_NAME TB_PONTO_ENE
TABLE_TYPE TABLE
TEMPORARY N
UNIQUENESS UNIQUE
USER_STATS NO
Two other things has come to my attention: the explain plan for select count(*) from thetable shows that the index is used at the test database, but shows a full table scan at the production database. Which led me to another observation: the test database index has 160MB and the production db has more than 1GB (and we don't do deletes on this table).
Can anyone point me to the solution?
UPDATE
Here are the execution plans:
Test database:
Execution Plan
----------------------------------------------------------
Plan hash value: 1441290166
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 18767 (4)| 00:03:46 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| IDX_HV_TB_PONTO_ENE | 28M| 18767 (4)| 00:03:46 |
-------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
111 recursive calls
0 db block gets
83586 consistent gets
83533 physical reads
0 redo size
422 bytes sent via SQL*Net to client
399 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
1 rows processed
Production database
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=RULE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'TB_PONTO_ENE'
Statistics
----------------------------------------------------------
1 recursive calls
3 db block gets
605327 consistent gets
603698 physical reads
180 redo size
201 bytes sent via SQL*Net to client
242 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
UPDATE 2
The production server is running Oracle 9.2.0.
UPDATE 3
Here are the statistics for the execution with the optimizer mode set to CHOOSE:
SQL> SELECT dt_hr_instante, vl_eneat_del,vl_eneat_rec,vl_enere_del, vl_enere_rec FROM tb_ponto_ene WHERE cd_ponto = 31 AND dt_hr_instante BETWEEN to_date('01/06/2010 00:05:00','dd/mm/yyyy hh24:mi:ss') AND to_date('01/07/2010 00:00:00', 'dd/mm/yyyy hh24:mi:ss');
8640 rows selected.
Elapsed: 00:01:49.51
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=1 Bytes=36)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TB_PONTO_ENE' (Cost=4 Card=1 Bytes=36)
2 1 INDEX (RANGE SCAN) OF 'CP_TB_PONTO_ENE' (UNIQUE) (Cost=3 Card=1)
Statistics
----------------------------------------------------------
119 recursive calls
0 db block gets
9169 consistent gets
7438 physical reads
0 redo size
308524 bytes sent via SQL*Net to client
4267 bytes received via SQL*Net from client
577 SQL*Net roundtrips to/from client
6 sorts (memory)
0 sorts (disk)
8640 rows processed
The Test database indexes properties include IOT_REDUNDANT_PKEY_ELIM and DROPPED columns but not the production indexes. These columns were added in oracle 10g.
Is perhaps the production database running under the old 9i version and the test database under 10g ? If so, I'd consider that a more significant difference than anything else.
That said if "select count(*) from thetable" is not using a primary key index it is very odd. The index stats are very out of date (14,004,395 rows when you suggest there's over 30 million and last gathered in March). If the table has doubled in size in the last six months, and its stats are even older, then it might be an issue.
The autotrace plan for production says "RULE" optimizer. If you look at the Oracle Tuning document (9i) section RBO Path 15: Full table scan it clearly states full table scan will be used.

Resources