I am testing an application on two database servers with the same data :
- 10.1.0.2 on Windows (for development)
- 10.2.0.5 on Solaris (for validation).
We have a script which recreates a huge table (> 100 millions of rows) and its index. The performance for doing this is OK on both platforms and we get almost the same times (about 1 hour).
The structure is created as follows:
CREATE TABLE "PART"
(
"PARTNUMBER" VARCHAR2(9 BYTE) NOT NULL ENABLE,
"SUBPARTNUMBER" VARCHAR2(12 BYTE) NOT NULL ENABLE,
"ISSUE" VARCHAR2(3 BYTE),
"PROG" VARCHAR2(1 BYTE) NOT NULL ENABLE,
"TYPE" VARCHAR2(1 BYTE) NOT NULL ENABLE,
"TYPE_NAME" VARCHAR2(25 BYTE),
"FROM" NUMBER(4,0) NOT NULL ENABLE,
"TO" NUMBER(4,0) NOT NULL ENABLE
);
CREATE INDEX "PART_INDEX" ON "PART" ("PARTNUMBER", "TO", "FROM", "TYPE_NAME") COMPRESS;
Then we gather statistics on the table (and implicitly on the index):
dbms_stats.gather_table_stats(null,'PART');
There is a performance issue on a query which takes less than 5 second on the 10.1.0.2 but more than 5 minutes on the 10.2.0.5:
SELECT DISTINCT
p.SUBPARTNUMBER,
p.PROG,
p.TYPE,
p.TYPE_NAME
FROM PART p, VW_VEHICLES v
WHERE p.PARTNUMBER= 'A12345678'
AND p.PROG = v.PROG
AND p.TYPE = 'V'
AND v.TYPE_NAME = p.TYPE_NAME
AND v.RANK BETWEEN p.FROM AND p.TO
ORDER BY p.PARTNUMBER;
I looked at the statistics tab in SQLDeveloper on both platform, it is similar for the TABLE, but for the index there is a big difference on the key DISTINCT_KEYS
:
- 10.1.0.2 : DISTINCT_KEYS = 144800
- 10.2.0.5 : DISTINCT_KEYS = 44404445
Do you know what can explain these differences ?
The second server (Solaris) should be more powerful and more efficient than the Windows one which is a workstation with less memory and inefficient HDD.
Here are the explain plans for both platforms:
- 10.1.0.2
--------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |IN-OUT| --------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 11 | 759 | 8291 (1)| 00:01:40 | | | | 1 | SORT ORDER BY | | 11 | 759 | 8291 (1)| 00:01:40 | | | | 2 | SORT UNIQUE | | 11 | 759 | 8290 (1)| 00:01:40 | | | |* 3 | HASH JOIN | | 11 | 759 | 8289 (1)| 00:01:40 | | | | 4 | VIEW | | 2795 | 81055 | 114 (-12)| 00:00:02 | | | | 5 | UNION-ALL | | | | | | | | | 6 | REMOTE | | 1 | 32 | 1 (0)| 00:00:01 | VEHIC~ | R->S | | 7 | REMOTE | | 7790 | 281K| 14 (0)| 00:00:01 | VEHIC~ | R->S | |* 8 | TABLE ACCESS BY INDEX ROWID| PART | 6579 | 256K| 8159 (1)| 00:01:38 | | | |* 9 | INDEX RANGE SCAN | PART_INDEX | 1 | | 41 (0)| 00:00:01 | | | ---------------------------------------------------------------------------------------------------------------------------
- 10.2.0.5
-------------------------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Inst |IN-OUT| -------------------------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 69 | 302 (1)| 00:00:05 | | | | 1 | SORT ORDER BY | | 1 | 69 | 302 (1)| 00:00:05 | | | | 2 | SORT UNIQUE | | 1 | 69 | 301 (1)| 00:00:05 | | | |* 3 | TABLE ACCESS BY INDEX ROWID| PART | 1 | 40 | 3 (0)| 00:00:01 | | | | 4 | NESTED LOOPS | | 1 | 69 | 300 (0)| 00:00:05 | | | | 5 | VIEW | | 100 | 2900 | 5 (100)| 00:00:01 | | | | 6 | UNION-ALL | | | | | | | | | 7 | REMOTE | | | | | | VEHIC~ | R->S | | 8 | REMOTE | | | | | | VEHIC~ | R->S | |* 9 | INDEX RANGE SCAN | PART_INDEX | 1 | | 2 (0)| 00:00:01 | | | --------------------------------------------------------------------------------------------------------------------------
I am also trying to investigate on a 11g…
Best Answer
You say
but statistics on indexes aren't gathered unless you do this:
What appears to be happening is index statistics are not being gathered (or not gathered correctly) on 10.2.0.5; if specifying
cascade=>true
doesn't help, you may want to consider gathering the index statistics separately viadbms_stats.gather_index_stats(null, 'PART_INDEX', estimate_percent=>20)
. You might also need to set a higher value for estimate_percent.You may also want to ensure you have set system statistics (which tell the optimizer how fast your disks are, how much CPU you have, etc.) via the
dbms_stats.gather_system_stats
anddbms_stats.set_system_stats
procedures. I think that 10.2 is more sensitive to system statistics.