# Oracle - Indizes werden nicht genommen



## heidiweber (3. Jun 2009)

Hallo,

ich teste gerade die Performance einer Datenbank.

Es wurden 2 Tabellen angelegt:


```
CREATE TABLE "BI"."RHKC_2007_KO_KLEIN" 
   (	"ID" NUMBER(18,0) NOT NULL ENABLE, 
	"KENR13" NUMBER(1,0), 
	"BRNR" NUMBER(2,0),
             "BEJA" NUMBER(4,0)
   )

CREATE INDEX "BI"."RHKC_2007_IDX4" ON "BI"."RHKC_2007_KO_KLEIN" ("BEJA")
CREATE UNIQUE INDEX "BI"."PK_KLEIN_KO_ID" ON "BI"."RHKC_2007_KO_KLEIN" ("ID")
```



```
CREATE TABLE "BI"."RHKC_2007_MC_KLEIN" 
   (	"ID" NUMBER(18,0) NOT NULL ENABLE, 
	"BRNR" NUMBER(2,0), 
	"PSGRAL" NUMBER(1,0), 
	"PSGRSO" NUMBER(1,0)
   )
CREATE INDEX "BI"."IDX_RHKC2007MC_ID" ON "BI"."RHKC_2007_MC_KLEIN" ("ID")
```

Auf den ID Spalten der beiden Tabellen liegen Indizes. Ausserdem noch ein Bitmap-Index auf BEJA.

Jetzt mache ich folgende Abfrage:


```
delete plan_table;

explain plan
set statement_id = 'MY_STATE'
for
select * from rhkc_2007_ko_klein a, rhkc_2007_mc_klein b where beja = 2007 and a.id = b.id

select lpad(' ',2*level)||OPERATION||' '||OPTIONS||' '||OBJECT_NAME QUERY_PLAN
from PLAN_TABLE WHERE STATEMENT_ID = 'MY_STATE'
connect by prior id = PARENT_ID AND STATEMENT_ID = 'MY_STATE' 
start with id = 1;
```


Als Errgebnis kommt:


```
PX COORDINATOR  
    PX SEND QC (RANDOM) :TQ10001
      HASH JOIN  
        PX RECEIVE  
          PX SEND BROADCAST LOCAL :TQ10000
            PX BLOCK ITERATOR 
              TABLE ACCESS FULL RHKC_2007_KO_KLEIN
        PX BLOCK ITERATOR 
          TABLE ACCESS FULL RHKC_2007_MC_KLEIN
```

Kann mir vielleicht bitte jemand sagen, wieso er einen FullTableScan macht und nicht auf die Indizes geht? Zumindest der Join über beide Tabellen sollte doch über die Indizes gehen? 

Vielen Dank
Grüße
Heidi


----------



## kama (3. Jun 2009)

Hallo,



heidiweber hat gesagt.:


> ```
> CREATE TABLE "BI"."RHKC_2007_KO_KLEIN"
> (	"ID" NUMBER(18,0) NOT NULL ENABLE,
> "KENR13" NUMBER(1,0),
> ...


Wo sind denn hier die primary keys ? In dem sog. Join werden nur die ID-Spalten der Tabellen in Beziehung gesetzt....aber ich sehen nirgendwo ein Feld, dass auch den Fremdschlüssel z.B. der zweiten Tabelle enthält...z.B. al la: "FK_MC_KLEIN" oder so etwas...und dazu gehört dann ein foreign Key Constraint....
MfG
Karl Heinz Marbaise


----------



## heidiweber (3. Jun 2009)

Hallo,

habe leider nicht alles gepostet - dachte das langt


```
CREATE TABLE "BI"."RHKC_2007_KO_KLEIN" 
   (	"ID" NUMBER(18,0) NOT NULL ENABLE, 
	"KENR13" NUMBER(1,0), 
	"BRNR" NUMBER(2,0),
             "BEJA" NUMBER(4,0),
	 CONSTRAINT "PK_KLEIN_KO_ID" 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)
             TABLESPACE "OWB_TSP"  ENABLE
   )
```


```
CREATE TABLE "BI"."RHKC_2007_MC_KLEIN" 
   (	"ID" NUMBER(18,0) NOT NULL ENABLE, 
	"BRNR" NUMBER(2,0), 
	"PSGRAL" NUMBER(1,0), 
	"PSGRSO" NUMBER(1,0),
	 CONSTRAINT "FK_MC_ID" FOREIGN KEY ("ID")
	  REFERENCES "BI"."RHKC_2007_KO_KLEIN" ("ID") ENABLE
   )
```

PrimaryKey und ForeignKey sind meiner Meinung nach angelegt.
Trotzdem macht er einen FullTableScan.
Oder was fehlt da noch?


----------



## heidiweber (4. Jun 2009)

Guten Morgen,

hat keiner eine Erklärung für das Verhalten? Sollte Oracle die Indizes bei der Abfrage nehmen? Oder kann man den FullTableScan doch erklären?

Vielen Dank
Grüße
Heidi


----------



## ice-breaker (4. Jun 2009)

Das kommt auch auf die Verteilung der Daten an, wenn Oracle denkt, das ein Fulltable-Scan effektiver ist, weil die 2007_ko_klein Spalte zu wenig Daten hat, oder wenn der Index zuviele Daten selected, so dass ein FS effektiver ist, dann wird es das auch tun.

Mehr kann ich dir da leider nicht helfen, da ich Optimierungen in MySQL mache, und nicht weiß welche Heuristiken bzw. Eigenheiten Oracle noch hat.


----------



## heidiweber (4. Jun 2009)

Vielen Dank euch beiden.

Habe jetzt mal testweise in einer anderen Oracle-11g-DB "Spieltabellen" und Indizes... angelegt und es geht. Er nimmt die Indizes. Ganz genau so gemacht. Nur mit erheblich weniger Daten? Da macht ein FullTableScan ja keinen Unterschied.

Vielleicht passt doch was anderes nicht? Glaube, da muss ich Oracle kontaktieren.

Schönen Abend
Grüße
Heidi


----------



## sayang (17. Jun 2009)

Hallo,

wie sieht denn dein Explain-Plan aus, wenn du 

  select * from rhkc_2007_ko_klein a, rhkc_2007_mc_klein b where "BEJA" = 2007 and a.id = b.id

verwendest (also statt beja = 2007 "BEJA" = 2007)?

Ich war eigentlich immer der Meinung, dass Spalten-Namen, die in "" gesetzt werden case-sensitive sind. Und die BEJA-Spalte wurde ja auch mit "" angelegt und auch der Index wurde mit "BEJA" angelegt. Aber im SELECT notierst du die Spalte als beja (ohne die "").

Lg
sayang


----------

