Avatar billede slott_hansen Nybegynder
20. september 2001 - 11:40 Der er 18 kommentarer og
1 løsning

Explain/Optimering

PostgreSQL har desværre en kedelig bagside - den styrre ikke rigtig brugen af indexes m.m. Men hvor om alt er, så skal jeg altså bruge postgreSQL og må derfor finde en løsning.

Se på følgende tabeller:

CREATE TABLE \"folder2\" (
        \"id\" int4 NOT NULL,
        \"title\" character varying(255) NOT NULL,
        \"keywords\" character varying(255),
        \"description\" text,
        \"sort_by\" character varying(10) NOT NULL,
        \"folder_type\" character varying(10),
        Constraint \"folder_pkey\" Primary Key (\"id\")
);

CREATE TABLE \"objects2\" (
        \"num_id\" int4 DEFAULT nextval(\'objects_num_id_seq\') NOT NULL,
        \"id\" int4 NOT NULL,
        \"parent\" character varying(40) NOT NULL,
        \"site_id\" character varying(40) NOT NULL,
        \"type\" character varying(20) NOT NULL, 
        \"sort_order\" int4 NOT NULL,
        \"date_updated\" timestamp with time zone NOT NULL,
        \"user_id\" character varying(40) NOT NULL,
        \"status\" int2 DEFAULT 1 NOT NULL,
        Constraint \"objects_pkey\" Primary Key (\"id\")
);
create index objects_status_index on objects2(status);


Og se så hvad der sker...

explain
select t1.id, t1.sort_by
from folder t1, objects t2
where t1.id = t2.id
and status = int2(1) or status = int2(0)
and sort_by <> \'manual\'
;

Nested Loop  (cost=0.00..55276.84 rows=23425 width=38)
  ->  Index Scan using objects_status_index, objects_status_index on objects t2  (cost=0.00..1241.48 rows=1201 width=14)
  ->  Seq Scan on folder t1  (cost=0.00..20.00 rows=1000 width=24)

Den laver en Seq scan på folder2 tabellen selv om der er index på id! Det sjove er så, at fjerner jeg status sammenligningen, så benytter den index\'et på folder2 tabellen - total trist at det er sådan.

Bemærk iøvrigt hvordan det er nødvendigt at typecaste for at få den til at benytte index på status kolonnen...
Avatar billede coderdk Praktikant
20. september 2001 - 14:45 #1
Hvad med indexes på id felterne?
Avatar billede slott_hansen Nybegynder
20. september 2001 - 14:46 #2
Constraint sætter automatisk index på...
Avatar billede coderdk Praktikant
20. september 2001 - 14:46 #3
Læste lige færdigt... Ud fra det du har skrevet er der da ikke index på id...
Avatar billede coderdk Praktikant
20. september 2001 - 14:47 #4
Ja det er da osse rigtigt... Jeg er bare lidt sløv idag :(
Avatar billede coderdk Praktikant
20. september 2001 - 14:49 #5
Har du set om den rent faktisk har lavet indexerne på  id?
Avatar billede slott_hansen Nybegynder
20. september 2001 - 14:54 #6
Yup - den er god nok. Postgres er bare lidt for dum til at bruge dem...
Avatar billede aggie Nybegynder
01. oktober 2001 - 16:11 #7
ej, folkens, rtfm inden i dizzer databasen..

pgsql bruger for det første automatisk oid\'s - prøv at skrive

SELECT oid,* FROM <et-eller-andet-table>

De er unikke for hver enkelt row i hele databasen - brug dog dem?

der er iøvrigt noget meget uheldigt ved din konstruktion - \'Rule of left indexing\' - dvs, at indekserede kolonner skal holdes til venstre, og ordnet efter hvor tit du vælger ud fra dem - eksempel:

hvis man har et fodboldhold,

spiller_id (unik key),
troeje_nr (indekseret),
cpr_nr (indekseret),
navn

vil man kunne drage nytte af alle tre indexes hvis man vælger f.eks.

SELECT spiller_id,troeje_nr,cpr_nr,navn

men hvis tabellen er således:

spiller_id (unik key),
navn,
troeje_nr (indekseret),
cpr_nr (indekseret)

- så kan kun index på spiller_id benyttes, fordi man har en ikke indekseret kolonne i midten.. derfor er det en ide at indeksere de kolonner der er længst til venstre.

Derudover er det vigtigt, at indeksere kolonner der har mange værdier - hvis status for eksempel har 3-4 mulige værdier, skal databasen jo stadig trawle gennem 1/# - 1/4 af databasen..
Avatar billede slott_hansen Nybegynder
01. oktober 2001 - 16:21 #8
Alt hvad ud skriver har jeg alerede styr på - men tillad mig lige at uddybe nu da du har skrevet så meget:

oid kan jeg ikke bruge til meget, da jeg er nød til at havde styr på id\'erne - de skal jo bruges til at samle flere tabeller!!! Så oid på den ene tabel er ikke at finde i den anden!

Rækkefølgen af index\'es er også klar nok - men heller ikke lige det der burde give mig problemer jvf. mit eks.

Og ja - der ER jo index på status, da denne kan antage værdierne 0,1,10 og 11.

Men ellers tak for svaret - det hjælper mig sog desværre ikke meget videre...;-(
Avatar billede aggie Nybegynder
01. oktober 2001 - 17:17 #9
de id\'s der - er det fordi de skal bruges som foreign keys?
Avatar billede slott_hansen Nybegynder
02. oktober 2001 - 09:35 #10
PT er det ikke foreign keys - men de binder tabellerne sammen. Der er en objekt tabel med id numre, som referere til andre tabeller via. denne entydige nøgle (id).

På sigt skal de naturligvis laves til foreign keys - men det er ikke noget der sker idag eller imorgen.
Avatar billede aggie Nybegynder
02. oktober 2001 - 10:14 #11
Jamn, det er jo det oid\'s er til;

- de er automatisk indekseret,
- de er garanteret unikke,
- de fjerner id\'s fra ens åsyn, så tabellerne alt andet lige bliver lettere at overskue.

Der er jo så også et par svagheder;

- man kan ikke UPDATE på dem (men godt på resten af tabellen),
- de er ikke sekventielle,

hvis det er et problem med nogle af delene, skal man bruge SERIAL eller sequences..

Men det du siger med at samle tabeller;

jeg har en database, med nogle firmaer, og nogle produkter, der ser således ud;

CREATE TABLE firma(
name varchar(128),
cvr decimal(7),
account_in varchar(64),
account_out varchar(64)
);

CREATE TABLE vare(
fabrik_id OID,
firma_id OID,
retailer_id OID,
serial_number varchar(64),
title varchar(128),
description text
);

hvor firma_id (OID) refererer til det indbyggede OID på firmas tabellen. Ligesom dig skal jeg på sigt have lavet foreign keys formelt, men det her virker ganske fint for nu, og er for så vidt ikke anderledes end de indexes jeg plejer at bruge i mysql..
Avatar billede slott_hansen Nybegynder
02. oktober 2001 - 10:18 #12
Det er jo fint nok - men jeg er nød til at holde mig til laveste fællesnævner. Alt hvad jeg laver SKAL kunne køre på MySQL, postgreSQL, Oracle og MSQL - og hvad der ellers måtte være. Jeg har lavet det fede database abstraktionslag - så det spiller bare...
Avatar billede aggie Nybegynder
02. oktober 2001 - 11:10 #13
nåja, men hvis du går efter laveste fællesnævner, skal du jo nok ikke undre dig over, at de enkelte databaser ikke kører optimalt :)
Avatar billede slott_hansen Nybegynder
02. oktober 2001 - 11:16 #14
He he - det er selvfølgelig rigtigt nok; men aligevel! Mit problem oven for med id kolonnen som primary key burde virke og postgres burde bruge det index der automatisk oprettes...
Avatar billede aggie Nybegynder
02. oktober 2001 - 11:40 #15
nåja, det var jo det det hele drejede sig om :)

hvordan opfører den sig hvis du laver den som subselect istedet for join?
Avatar billede slott_hansen Nybegynder
02. oktober 2001 - 11:42 #16
Thats out of the question - mySQL understøtter ikke subselect... ;-(
Avatar billede aggie Nybegynder
02. oktober 2001 - 13:12 #17
Jeg er lige faldet over nogel interessante ting i dokumentationen omkring explain, som jeg har meget spas med selv,
det virker som om query-optimizer/planner aben træffer beslutningen om, hvorvidt der skal bruges sequential eller index scan, ud fra nogle obskure kriterier..

Du kan læse mere om den, og om hvordan man evt. kan tilsidesætte dens snedige regler på

http://www.postgresql.org/idocs/index.php?planner-optimizer.html

- det kunne hjælpe, fordi det piller ved din rdbm istedet for koden, så du holder dig stadig indenfor den laveste fællesnævner :)
Avatar billede slott_hansen Nybegynder
02. oktober 2001 - 13:16 #18
Lyder interessant - det vil jeg se på senere... Men lad os holde debatten åben indtil jeg ved mere...
Avatar billede aggie Nybegynder
02. oktober 2001 - 13:31 #19
fino :)

kig endelig ind på

http://www.eksperten.dk/spm/115744 ,

så kan det være at jeg kan hjælpes :)
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