16. oktober 2006 - 12:16Der 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
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
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.
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).
Synes godt om
Ny brugerNybegynder
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.