Avatar billede amoelle Nybegynder
02. januar 2006 - 10:31 Der er 7 kommentarer og
1 løsning

join - forbedring af performance

Jeg har en query, der tager urimeligt lang tid...
Er der nogle gode tips til at forbedre performance på den ?


select distinct a.kode
from table_a a
join schema_b.table_b b on
(b.kode = a.kode)
join table_c c on
(c.klasse=a.guid)
)



SQL> desc table_a  /* 230.000 records */
Navn      NULL?    Type
--------- -------- -----------------------
PK        NOT NULL NUMBER(38)
GUID      NOT NULL VARCHAR2(40)
KODE              VARCHAR2(1000)

SQL> desc table_b  /* 65.000 records */
Navn      NULL?    Type
--------- -------- -----------------------
PK        NOT NULL NUMBER(38)
GUID      NOT NULL VARCHAR2(40)
KODE              VARCHAR2(1000)

SQL> desc table_c  /* 260.000 records */
Navn      NULL?    Type
--------- -------- ------------------------
PK        NOT NULL NUMBER(38)
GUID      NOT NULL VARCHAR2(40)
KLASSE    NOT NULL NUMBER(38)


/Anne
Avatar billede bhn.314 Nybegynder
02. januar 2006 - 10:44 #1
Har du lavet index på de værdier du join'er.....
Avatar billede pgroen Nybegynder
02. januar 2006 - 10:47 #2
Du har vel indekser på a.kode, b.kode, c.klasse og a.guid ?

og i øvrigt har du en implicit typekonvertering, når du joiner klasse (NUMBER) og guid (VARCHAR2) - er det hensigten ?
Avatar billede amoelle Nybegynder
02. januar 2006 - 10:57 #3
der var ikke index på dem alle,.... det prøver jeg lige...

Og ja, der er implicit typekonvertering, og også noget instr/substr/lower konvertering.
Det var bare pillet ud for at simplificere selectet.

Jeg troede den dårlige performance skyldtes uklog brug af join rækkefølge,- men det kan være at manglende indices er den store synder ?....


select distinct a.kode
from table_a a, 
join schema_b.table_b b on
(lower(b.kode) like '%'|| lower(substr(a.kode,10))
join table_c c on
(c.klasse=a.guid)
(c.klasse=substr(a.guid, instr(a.guid, '/', 1, 1) + 1, length(a.guid)))
)
Avatar billede pgroen Nybegynder
02. januar 2006 - 12:23 #4
Aha, så burde du måske overveje at bruge function-based indexes...
fx. CREATE INDEX <indexnavn> ON table_a (lower(substr(kode,10))); -- osv..
Avatar billede Slettet bruger
02. januar 2006 - 18:21 #5
som dit udtryk ser ud nu, er det tabel a der er drivende. Men tabel b har kun 65.000 rækker. Det er langt færre end tabel a's 230.000 rækker. Måske skulle du lave dit select om til et select på b:

select distinct b.kode
from ...
Avatar billede amoelle Nybegynder
03. januar 2006 - 16:04 #6
tak for gode input som tilsammen løste mit problem.
Jeg har tilføjet temporære kolonner( med den udregnede værdi) i tabellerne med de forskellige kolonner, hvor jeg anvender funktioner, - og herfter er der lavet midlertidige indices på disse kolonner. Der nu nu således ikke hverken implicit eller eksplicit konvertering af typer eller strenge. Dernæst har jeg lavet tabel_b til den drivende.
En explain plan viser nu at den store synder er 
....like '%'||a.lower_10_fuldkode....
men den kan jeg ikke slippe udenom, så det bliver ikke bedre.

Byd ind med svar, så får I points
/Anne
Avatar billede Slettet bruger
03. januar 2006 - 18:45 #7
hvis du skal bruge indekset 'table_a (lower(substr(kode,10)))' til noget skal du have 'vendt' det om. 'Like '%' || ...'  gør jo at det ikke kan bruges, fordi indekset ikke 'starter' med en værdi der kan slås op i indekset. ...

Du burde lave indeks på 'revers(lower(b.kode))' og 'revers(lower(substr(kode,10))))'.

Jeg ved ikke om der findes en 'revers'-funktion. Men den kunne man jo hurtigt lige lave
Avatar billede pgroen Nybegynder
03. januar 2006 - 21:32 #8
Hov, joern_h har da helt ret;

Kunne man (uden at jeg har prøvet det efter) skrive joinen om til noget i stil med:

lower(b.kode) = lower(substr(a.kode,-(length(a.kode)-10))) ?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester