sql >> Database >  >> RDS >> PostgreSQL

Wat vertelt PostgreSQL mij precies?

Het deel dat ik altijd verwarrend vond, zijn de opstartkosten versus de totale kosten. Ik Google dit elke keer als ik het vergeet, wat me hier terugbrengt, wat het verschil niet verklaart, daarom schrijf ik dit antwoord. Dit is wat ik heb afgeleid uit de Postgres EXPLAIN documentatie, uitgelegd zoals ik het begrijp.

Hier is een voorbeeld van een applicatie die een forum beheert:

EXPLAIN SELECT * FROM post LIMIT 50;

Limit  (cost=0.00..3.39 rows=50 width=422)
  ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

Hier is de grafische uitleg van PgAdmin:

(Als u PgAdmin gebruikt, kunt u met uw muis naar een onderdeel gaan om de kostendetails te lezen.)

De kosten worden weergegeven als een tupel, b.v. de kosten van de LIMIT is cost=0.00..3.39 en de kosten van het achtereenvolgens scannen van post is cost=0.00..15629.12 . Het eerste getal in de tuple zijn de opstartkosten en het tweede getal is de totale kosten . Omdat ik EXPLAIN heb gebruikt en niet EXPLAIN ANALYZE , deze kosten zijn schattingen, geen werkelijke maatregelen.

  • Opstartkosten is een lastig begrip. Het vertegenwoordigt niet alleen de hoeveelheid tijd voordat dat onderdeel start . Het vertegenwoordigt de hoeveelheid tijd tussen het moment waarop de component wordt uitgevoerd (gegevens inlezen) en wanneer de component de eerste rij uitvoert .
  • Totale kosten is de volledige uitvoeringstijd van het onderdeel, vanaf het moment dat het begint met het inlezen van gegevens tot het moment waarop het klaar is met het schrijven van de uitvoer.

Als een complicatie omvatten de kosten van elk "ouder" knooppunt de kosten van zijn onderliggende knooppunten. In de tekstweergave wordt de boom weergegeven door inspringing, b.v. LIMIT is een bovenliggende node en Seq Scan is zijn kind. In de PgAdmin-weergave wijzen de pijlen van kind naar ouder - de richting van de gegevensstroom - wat contra-intuïtief kan zijn als u bekend bent met grafentheorie.

De documentatie zegt dat de kosten inclusief alle onderliggende nodes zijn, maar merk op dat de totale kosten van de bovenliggende 3.39 is veel kleiner dan de totale kosten van zijn kind 15629.12 . De totale kosten zijn niet inclusief omdat een onderdeel zoals LIMIT hoeft niet de volledige invoer te verwerken. Zie de EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2; voorbeeld in Postgres EXPLAIN documentatie.

In het bovenstaande voorbeeld is de opstarttijd voor beide componenten nul, omdat geen van beide componenten enige verwerking hoeft uit te voeren voordat het rijen begint te schrijven:een sequentiële scan leest de eerste rij van de tabel en verzendt deze. De LIMIT leest de eerste rij en zendt deze vervolgens uit.

Wanneer zou een component veel verwerking moeten doen voordat het rijen kan gaan uitvoeren? Er zijn veel mogelijke redenen, maar laten we een duidelijk voorbeeld bekijken. Hier is dezelfde zoekopdracht van vroeger, maar nu met een ORDER BY clausule:

EXPLAIN SELECT * FROM post ORDER BY body LIMIT 50;

Limit  (cost=23283.24..23283.37 rows=50 width=422)
  ->  Sort  (cost=23283.24..23859.27 rows=230412 width=422)
        Sort Key: body
        ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

En grafisch:

Nogmaals, de sequentiële scan op post heeft geen opstartkosten:het begint onmiddellijk met het uitvoeren van rijen. Maar de soort heeft aanzienlijke opstartkosten 23283.24 omdat het de hele tabel moet sorteren voordat het zelfs maar een enkele rij kan uitvoeren . De totale kosten van de soort 23859.27 is slechts iets hoger dan de opstartkosten, wat het feit weerspiegelt dat zodra de hele dataset is gesorteerd, de gesorteerde gegevens zeer snel kunnen worden verzonden.

Merk op dat de opstarttijd van de LIMIT 23283.24 is exact gelijk aan de opstarttijd van de soort. Dit is niet omdat LIMIT zelf heeft een hoge opstarttijd. Het heeft eigenlijk geen opstarttijd op zich, maar EXPLAIN rolt alle kindkosten voor elke ouder bij elkaar, dus de LIMIT opstarttijd omvat de som van de opstarttijden van zijn kinderen.

Deze opeenstapeling van kosten kan het moeilijk maken om de uitvoeringskosten van elk afzonderlijk onderdeel te begrijpen. Bijvoorbeeld onze LIMIT heeft nul opstarttijd, maar dat is op het eerste gezicht niet duidelijk. Om deze reden hebben verschillende andere mensen gelinkt naar explain.depesz.com, een tool gemaakt door Hubert Lubaczewski (ook bekend als depesz) die helpt bij het begrijpen van EXPLAIN door onder meer de kinderkosten af ​​te trekken van de ouderkosten. Hij noemt enkele andere complexiteiten in een korte blogpost over zijn tool.



  1. Fatale fout:oproep naar niet-gedefinieerde functie sqlsrv_connect()

  2. Spring + Hibernate:Query Plan Cache Geheugengebruik

  3. Sql Server tijdelijke tabel verdwijnt

  4. Vernieuw een gerealiseerde weergave automatisch met behulp van een regel of melding