Avatar billede shanders Nybegynder
15. februar 2001 - 12:48 Der er 14 kommentarer og
1 løsning

Optimering af SQL

Jeg har oprettet et SQL kald som tilgår 4 tabeller på baggrund af 2 indtastninger.

Problem: Der kan gå over 60 sek. ved søgning  :(
Hvis oplysningerne hentes med 4 SQL kald, et til hver tabel bruges der kun få sekunder.

Min teori er at det rette kald må kunne hente data næsten lige så hurtigt som de 4 individuelle kald.

Her er opstillingen:

Tabel : felter
-----------------------------------
ATABEL : NR1, NR2, ADATE, NR3
BTABEL : NR1, NR2, ADATE, NR4, BINFO
CTABEL : NR1, NR4, CINFO
DTABEL : NR3, DINFO

SQL
-----------------------------------
SELECT DISTINCT D.DINFO, C.CINFO, B.BINFO, A.NR1, A.NR2, A.ADATE
FROM ATABEL A, BTABEL B, CTABEL C, DTABEL D
WHERE B.NR1 = \'INDTAST1\' AND
B.NR2 LIKE \'INDTAST2%\' AND
A.NR1 = B.NR1 AND
A.NR2 = B.NR2 AND
A.ADATE >= SYSDATE AND
C.NR1 = B.NR1 AND
C.NR4 = B.NR4 AND
D.NR3 = A.NR3
ORDER BY D.DINFO, C.CINFO, B.BINFO
Avatar billede -mundi- Nybegynder
15. februar 2001 - 12:55 #1
hmm hvilken DB og hvor store er de tables ?
Avatar billede -mundi- Nybegynder
15. februar 2001 - 12:56 #2
sorry Det er vel en oracle når du poster det her :-) Men hvor Mange records er der i de tabeller ? 60 sekunder er lige i overkanten
Avatar billede shanders Nybegynder
15. februar 2001 - 13:02 #3
ATabel :  525.000
BTabel :  555.000
CTabel :    16.000
DTabel : 1.075.000
Avatar billede -mundi- Nybegynder
15. februar 2001 - 13:07 #4
hmm frokost, vender straks tilbage :-)
Avatar billede pou_vad Nybegynder
15. februar 2001 - 13:08 #5
Du skal bruge nogle Joins istedet

SELECT DISTINCT D.DINFO, C.CINFO, B.BINFO, A.NR1, A.NR2, A.ADATE
FROM ATABLE.A
INNER JOIN BTABEL
ON (A.NR1 = B.NR1 AND A.NR2 = B.NR2)
INNER JOIN CTABEL
ON (B.NR1 = C.NR1 AMD B.NR4 = B.NR4)
INNER JOIN DTABEL
ON A.NR3 = D.NR3
WHERE B.NR1 = \'INDTAST1\' AND B.NR2 = \'INDTAST2\' AND A.ADATA > SYSDATE
ORDER BY D.DINFO, C.CINFO, B.BINFO


Desuden vil det nok være en god ide at ligge et index på dine tabeller

/Pou_vad
Avatar billede shanders Nybegynder
15. februar 2001 - 13:08 #6
De index der findes på tabellerne er følgende:

ATabel : NR3, NR1, NR2, ADATE
BTabel : NR1, NR2
CTabel : NR1, NR4
DTabel : NR3
Avatar billede pou_vad Nybegynder
15. februar 2001 - 13:11 #7
Du skal også passe på med at bruge like, da den er meget krævende. hvis det kan lade sig gøre er det meget hurtigere at bruge =
Avatar billede shanders Nybegynder
15. februar 2001 - 13:43 #8
Overstående giver : sql command not properly ended

B, C og DTabel skal vel også tildeles alias .B .C .D
Avatar billede pou_vad Nybegynder
15. februar 2001 - 13:58 #9
prøv at tilføje et GO

ellers kig på :
http://lonestar.subnet.dk/0-672-31110-0/
Avatar billede shanders Nybegynder
15. februar 2001 - 16:05 #10
HMMM TAK :(
Det hjælper mig ikke rigtig !

Hvad kan grunden være at joins (alle underlige afprøvede varianter) giver: sql command not properly ended ?

eks.
SELECT * FROM VEJ A
INNER JOIN POSTBY B
ON (A.POSTNR = B.POSTNR)

Ifølge al den dokumentation som jeg selv kunne finde, skulle overstående virke ???
Avatar billede pou_vad Nybegynder
16. februar 2001 - 10:17 #11
Jeg må indrømme at jeg kun har prøvet at lave Joins på en MS SQL - Men du burde virke på Oracel, da de begge skulle overholde SQL standarden
Avatar billede teepee Nybegynder
19. februar 2001 - 10:45 #12
Outer join i Oracle:

select *
from a, b
where a.id = b.id(+);

=> a vises selvom b ikke findes

Inner join i Oracle:

select *
from a, b
where a.id = b.id;

=> a vises kun når b findes

Dette medfører da også at din indledende SQL er ganske korrekt. Det er nok nærmere et index spørgsmål. Måske skal du prøve at sætte join-betingelserne (alle dem med ligmedtegn (=) i) op forrest og lade dine like og datoting stå til allersidst.

Kommentar til pou_vad: Siden hvornår har MS overholdt SQL ANSI standarden?
Avatar billede kibeha Nybegynder
19. februar 2001 - 15:16 #13
To muligheder :

Rækkefølgen af tabellerne i FROM kan have noget at sige, prøv med :

SELECT DISTINCT D.DINFO, C.CINFO, B.BINFO, A.NR1, A.NR2, A.ADATE
FROM BTABEL B, ATABEL A, CTABEL C, DTABEL D
WHERE B.NR1 = \'INDTAST1\' AND
B.NR2 LIKE \'INDTAST2%\' AND
A.NR1 = B.NR1 AND
A.NR2 = B.NR2 AND
A.ADATE >= SYSDATE AND
C.NR1 = B.NR1 AND
C.NR4 = B.NR4 AND
D.NR3 = A.NR3
ORDER BY D.DINFO, C.CINFO, B.BINFO

Altså \'hoved\'-tabellen i join først, sådan at når B er fundet, så er det at finde A, C og D ret simple opslag.

Mulighed nummer 2 :

Jeg gætter på din Oracle kører med Cost-based optimizer. Hvis det er tilfældet, så skal du have alle 4 tabeller analyseret, så optimizeren har noget at gå efter :

ANALYZE TABLE ATABEL COMPUTE STATISTICS;

(Du kan bruge ESTIMATE i stedet for COMPUTE - det går hurtigere, men er ikke så sikkert)
Avatar billede shanders Nybegynder
19. februar 2001 - 16:36 #14
Flytning af \'like\' gjorde stor udslag, jeg takker ;)

Cost-based optimizer ? det må desvære vente til jeg får lidt mere styr/tid på/til Oracle.
Avatar billede pou_vad Nybegynder
20. februar 2001 - 14:00 #15
Jeg har læst i MS documentationen et eller andet sted at de overholder SQL ANSI standarden - men det passer vel ikke :o)
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