Avatar billede michael_stim Ekspert
16. oktober 2006 - 12:16 Der er 4 kommentarer og
1 løsning

Formodentlig indekseringsproblem.

Nogen der ved hvordan man kan optimere denne forespørgsel?

SELECT DISTINCT id, mid, navn, (SELECT DISTINCT navn FROM sb_menu WHERE id=mid) AS mnavn, (SELECT count(*) FROM sb_doccounter WHERE mpid=m.id AND brugerid=1) AS docs FROM sb_menupunkt m GROUP BY mid, navn, id ORDER BY mid ASC;

Det er her flaskehalsen opstår:

(SELECT count(*) FROM sb_doccounter WHERE mpid=m.id AND brugerid=1)

Tabellerne.

SB_MENU:
ID                                        NOT NULL NUMBER
NAVN                                              VARCHAR2(50)
AKTIV                                              VARCHAR2(1)

SB_MENUPUNKT:
ID                                        NOT NULL NUMBER
NAVN                                              VARCHAR2(50)
AKTIV                                              VARCHAR2(1)
MID                                                NUMBER
VENSTREMENU                                        VARCHAR2(1)
OVERSKRIFT                                        VARCHAR2(50)
TEKST                                              CLOB

SB_DOCCOUNTER:
ID                                        NOT NULL NUMBER
BRUGERID                                          NUMBER
MID                                                NUMBER
MPID                                              NUMBER
DOCID                                              NUMBER
Avatar billede ldanielsen Nybegynder
16. oktober 2006 - 12:41 #1
Den første Subquery, "SELECT DISTINCT navn FROM sb_menu WHERE id=mid" (det skal vel være "SELECT DISTINCT navn FROM sb_menu WHERE id= m.mid"?) er et problem, for den må jo kun returnere 1 værdi. Derfor bør det være "SELECT TOP 1 navn FROM sb_menu WHERE id=m.mid".
Top 1 er MSSQL syntax, jeg kender ikke Oracle's syntax. Det burde dog helt erstattes af et JOIN, så det bliver:

SELECT DISTINCT m.id, m.mid, m.navn, mn.navn, (SELECT count(*) FROM sb_doccounter WHERE mpid = m.id AND brugerid = 1) AS docs FROM sb_menupunkt m LEFT OUTER JOIN sb_menu mn ON m.id = mn.id GROUP BY m.id, m.navn, m.mid, mn.navn ORDER BY mid ASC;

Ang. din Count skal der være index på mpid og brugerid i tabellen sb_doccounter
Avatar billede michael_stim Ekspert
16. oktober 2006 - 13:17 #2
Der er såmænd ikke nogle problemer med dataen der bliver hevet ud. Men prøver lige at indeksere (som jeg mistænkte).
Avatar billede michael_stim Ekspert
16. oktober 2006 - 13:41 #3
Det var indekseringen. Læg du bare et svar.
Avatar billede ldanielsen Nybegynder
16. oktober 2006 - 13:59 #4
OK

Du skulle nu bruge det join i stedet, det vil give meget bedre performance. Selv om det ikke gør den store forskel i dette tilfælde, så kan det betyde meget i et andet, lignende tilfælde.

Som sagt kender jeg ikke Oracle, men hvis den ligner andre databaser så giver man alle tabeller en primærnøgle, der naturligvis er unik, og den vil være det første index. Alle tabeller skal have en primærnøgle. Ofte bruger man et autonummereringsfelt til det.

Dernæst laver man indexer på fremmednøgler, dvs. de felter der bruges til alt linke to tabeller sammen. I dit tilfælde er det åbenbart fx. mid i sb_menupunkt.

Endelig kan det være nyttigt at indexere felter der bruges til at sortere efter, ofte et datofelt, samt felter der ofte bruges til at trække bestemte data ud, dvs. de felter der nævnes under WHERE-klausulen.
Avatar billede michael_stim Ekspert
16. oktober 2006 - 14:05 #5
Oracle er såmænd som de fleste andre relationsdatabaser. Alle mine id'er er autonummeringsfelter (desværre eksisterer et sådan felt ikke i Oracle, så det skal løses med triggers eller sequences).
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