sql >> Database teknologi >  >> RDS >> PostgreSQL

Langsom rækkefølge af forespørgsler efter en kolonne i en samlet tabel

Testcase

PostgreSQL 9.1. Testdatabase med begrænsede ressourcer, men nok til denne lille sag. Lokaliteten for sortering vil være relevant:

VIS LC_COLLATE; de_AT.UTF-8 

Trin 1) Rekonstruer råt testmiljø

-- SLIP TABEL x;CREATE SCHEMA x; -- testskema-- DROP TABLE x.django_site;CREATE TABLE x.django_site (id seriel primær nøgle,domænekarakter varierende(100) ikke null,int_col int ikke null);INSERT INTO x.django_site værdier (1,'www. testsite.com/foodir/', 3);-- DROP TABLE x.product;CREATE TABLE x.product ( id seriel primær nøgle, site_id heltal ikke null, navnetegn varierende(255) ikke null, slug-tegn varierende(255) ikke null,sku karakter varierende(255), bestillingsheltal ikke null,active boolean ikke null);INSERT INTO x.product (site_id, name, slug, sku, ordering, active)SELECT 1 ,repeat(chr((random() * 255)::int + 32), (random()*255)::int) ,repeat(chr((random() * 255)::int + 32), (random()*255)::int ), repeat(chr((random() * 255)::int + 32), (random()*255)::int) ,i -- rækkefølge ,NOT (random()* 0,5174346569119122)::int ::boolFROM generate_series(1, 17540) AS x(i);-- SELECT ((591::float8 / 17540)* 0,5) / (1 - (591::float8 / 17540))-- =0,5174346569119122EX product_site-id IND på x.product(site_id);

Trin 2) ANALYSER

ANALYSE x.produkt; ANALYSE x.django_site;

Trin 3) Omarranger BY random()

-- DROP TABLE x.p;CREATE TABLE x.p ASSELECT *FRA x.productORDER BY random();ANALYSE x.p; 

Resultater

EXPLAIN ANALYSE SELECT p.* FRA x.p JOIN x.django_site d ON (p.site_id =d.id) WHERE p.active AND p.site_id =1-- BESTILLE BY d.domain, p.ordering , s.navn-- BESTIL EFTER p.bestilling, s.navn-- BESTIL EFTER d.id, p.bestilling, s.navn-- BESTIL AF d.int_col, p.bestilling, s.navn-- BESTIL EFTER p. .name COLLATE "C"-- BESTIL AF d.domain COLLATE "C", p.ordering, p.name -- dvd's endelige løsning 

1) Pre ANALYSE (-> bitmap indeks scan)
2) Post ANALYSE (-> seq scan)
3) Omarranger efter tilfældig(), ANALYSER

ORDER BY d.domain, p.ordering, p.name 

1) Samlet kørselstid:1253.543 ms
2) Samlet kørselstid:1250.351 ms
3) Samlet kørselstid:1283.111 ms

ORDER BY p.ordering, p.name 

1) Samlet kørselstid:177.266 ms
2) Samlet kørselstid:174.556 ms
3) Samlet kørselstid:177.797 ms

ORDER BY d.id, p.ordering, p.name 

1) Samlet kørselstid:176.628 ms
2) Samlet kørselstid:176.811 ms
3) Samlet kørselstid:178.150 ms
Planlæggeren tager naturligvis højde for, at d.id er funktionelt afhængig.

BEstil AF d.int_col , p.ordering, p.navn -- heltalskolonne i anden tabel

1) Samlet kørselstid:242.218 ms -- !!
2) Samlet kørselstid:245.234 ms
3) Samlet kørselstid:254.581 ms
Planlæggeren savner åbenbart den d.int_col (IKKE NULL) er lige så funktionelt afhængig. Men det er billigt at sortere efter en heltalskolonne.

BEstil efter s.navn -- varchar(255) i samme tabel

1) Samlet kørselstid:2259.171 ms -- !!
2) Samlet kørselstid:2257.650 ms
3) Samlet kørselstid:2258.282 ms
Sortering efter en (lang) varchar eller tekst kolonne er dyr ...

ORDER BY p.name SAMLER "C" 

1) Samlet kørselstid:327.516 ms -- !!
2) Samlet kørselstid:325.103 ms
3) Samlet kørselstid:327.206 ms
... men ikke så dyrt, hvis det gøres uden lokalitet.

Med lokaliteten ude af vejen, sortering efter en varchar kolonne er ikke helt, men næsten lige så hurtig. Landestandard "C" er faktisk "ingen lokalitet, bare rækkefølge efter byteværdi". Jeg citerer manualen:

Hvis du ønsker, at systemet skal opføre sig, som om det ikke havde nogen lokalitetsunderstøttelse, skal du bruge det specielle lokalitetsnavn C eller tilsvarende POSIX.

Ved at sætte det hele sammen, valgte @dvd:

ORDER BY d.domain COLLATE "C", p.ordering, p.name 

...3) Samlet kørselstid:275.854 ms
Det burde du gøre.



  1. JSON_SET() – Indsæt eller opdater værdier i et JSON-dokument i MySQL

  2. Indsæt hvis det ikke findes, ellers returner id i postgresql

  3. hvor skal jeg placere installationsressourcer (wxs-fil, dmg-script, ikon) og hvordan man konfigurerer maven antrun, når jeg implementerer selvstændig app

  4. Sådan slutter du dig til første række