SlideShare una empresa de Scribd logo
1 de 33
Descargar para leer sin conexión
A deeper dive
into EXPLAIN
Michael Christofides
Hi, I’m Michael
Half of the team behind pgMustard
Spent a lot of time looking into EXPLAIN
Background: product management, database tools
pgmustard.com/docs/explain
michael@pgmustard.com
michristofides
Picking up from other EXPLAIN talks
Not the basics*
1) Some of the less intuitive arithmetic
2) Some less well covered issues
* postgresql.org/docs/current/performance-tips
thoughtbot: reading EXPLAIN ANALYZE
YouTube: Josh Berkus Explaining EXPLAIN
Picking up from other EXPLAIN talks
Not the basics*
1) Arithmetic: why is this query slow?
2) Issues: what can we do about it?
* postgresql.org/docs/current/performance-tips
thoughtbot: reading EXPLAIN ANALYZE
YouTube: Josh Berkus Explaining EXPLAIN
Arithmetic: loops
Many of the stats are a per-loop average
This includes costs, rows, timings
Watch out for rounding, especially to 0 rows
Disclaimer: heavily doctored
plans ahead, inaccuracies likely.
Nested Loop
(cost=0.84..209.82 rows=16 width=11)
(actual time=0.076..0.368 rows=86 loops=1)
-> Index Only Scan using a on b
(cost=0.42..4.58 rows=9 width=4)
(actual time=0.013..0.019 rows=9 loops=1)
-> Index Scan using x on y
(cost=0.42..22.73 rows=7 width=15)
(actual time=0.012..0.030 rows=10 loops=9)
Nested Loop: 86 rows
Index Scan: 9 * 10 = 90 rows
(Rounding not too bad here)
Arithmetic: threads
Costs, rows, and timings are also per-thread
Shown as loops
Threads = workers + 1
Tip: use VERBOSE
<- the leader
Parallel Seq Scan on table
(cost=0.00..6772.21 rows=79521 width=22)
(actual time=0.090..71.866 rows=63617 loops=3)
Output: column1, column2, column3
Worker 0: actual time=0.111..66.325 rows=56225 loops=1
Worker 1: actual time=0.138..66.027 rows=58792 loops=1
Seq Scan: 63617 * 3 = 190851 rows
Leader: 190851 - 58792 - 56225
= 75834 rows
Arithmetic: buffers
Buffer stats are a total, not per-loop
They are inclusive of children
Nested Loop (... loops=1)
Buffers: shared hit=105
-> Index Only Scan using a on b (... loops=1)
Buffers: shared hit=4
-> Index Scan using x on y (... loops=9)
Buffers: shared hit=101
Nested Loop buffers:
105 - (101 + 4) = 0 blocks
Arithmetic: timings
Per-loop, per-thread
Inclusive of children
Calculating per-node (exclusive) times can get
tricky, even for tools
Nested Loop
(cost=0.84..209.82 rows=16 width=11)
(actual time=0.076..0.368 rows=86 loops=1)
-> Index Only Scan using a on b
(cost=0.42..4.58 rows=9 width=4)
(actual time=0.013..0.019 rows=9 loops=1)
-> Index Scan using x on y
(cost=0.42..22.73 rows=7 width=15)
(actual time=0.012..0.030 rows=10 loops=9)
Index Scan: 0.030 * 9 = 0.27 ms
Nested Loop: 0.368 - 0.27 - 0.019
= 0.079 ms
WITH init AS (
SELECT * FROM pg_sleep_for('100ms')
UNION ALL
SELECT * FROM pg_sleep_for('200ms')
)
(SELECT * FROM init LIMIT 1)
UNION ALL
(SELECT * FROM init);
Credit @felixge
Append (actual time=100.359..
300.688 … )
CTE init
-> Append (actual time=100.334..
300.652 … )
-> Function Scan (actual time=100.333..
100.335 … )
-> Function Scan (actual time=200.310..
200.312 … )
-> Limit (actual time=100.358..
100.359 … )
-> CTE Scan a (actual time=100.355..100.356 … )
-> CTE Scan b (actual time=0.001..
200.322 … )
Execution Time: 300.789 ms
Further reading:
flame-explain.com/docs/general/quirk-correction
Some double-counting in this case.
Arithmetic: tools can help
eg explain.depesz.com
explain.dalibo.com
flame-explain.com
pgmustard.com
<- fellow calculations nerd
<- 👋
Issues: let’s skip the basics
Seq Scans with large filters
Bad row estimates
Sorts and Hashes on disk
Issues: inefficient index scans
Looks out for lots of rows being filtered
Filters are per-loop
So again, watch out for rounding
-> Index Scan using x on y
(cost=0.42..302502.05 rows=1708602 width=125)
(actual time=172810.219..173876.540 rows=1000 loops=1)
Index Cond: (id = another_id)
Filter: (status = 1)
Rows Removed by Filter: 3125626
Index efficiency: 1000/(1000+3125626) = 0.03%
Watch out for high loops
Issues: lossy bitmap scans
When bitmap would otherwise exceed work_mem
Point to a block rather than a row (Tuple Id)
Lossy blocks are a total (ie not per-loop)
-> Bitmap Heap Scan on table
(cost=49153.29..4069724.27 rows=3105598 width=1106)
(actual time=591.928..56472.895 rows=3853272 loops=1)
Recheck Cond: (something > something_else)
Rows Removed by Index Recheck: 5905323
Heap Blocks: exact=14280 lossy=1951048
Lossy blocks: 1951048/(1951048+14280) = 99%
Extra rows read: 5.9 million
Issues: lots of data read
Requires BUFFERS
Lots of data being read for the amount returned
Can be a sign of bloat
Default block size: 8kB
-> Index Scan using x on y
(cost=0.57..2.57 rows=1 width=8)
(actual time=0.064..0.064 rows=1 loops=256753)
Index Cond: (id = another_id)
Filter: (status = 1)
Buffers: shared hit=1146405 read=110636
Caveats: width estimated, rows rounded
Data read: (1146405 + 110636) * 8kB = 10GB
Data returned: 1 * 256753 * 8 bytes = 2MB
Issues: planning time
At the end of the query plan
Can be planning related: eg joins, partitions
But other things too: eg extensions, locks
Warning: not included in auto_explain
(...)
Planning Time: 27.844 ms
Execution Time: 11.162 ms
Planning proportion:
27.844/(27.844 + 11.162) = 71%
Issues: Just In Time compilation
At the end of the query plan
Included in execution time
On by default in PostgreSQL 12 and 13
Start-up time can be a tell-tale
Planning Time: 9.138 ms
JIT:
Functions: 277
Options: Inlining true, Optimization true, Expressions true,
Deforming true
Timing: Generation 31.602 ms, Inlining 253.114 ms, Optimization
1498.268 ms, Emission 913.945 ms, Total 2696.929 ms
Execution Time: 5194.851 ms
JIT proportion:
2696.929/(9.138 + 5194.851) = 52%
Very suspicious actual start-up time
from a JIT dominated plan.
-> Seq Scan on table
(cost=0.00..3.57 rows=72 width=8)
(actual time=2262.312..2262.343 rows=54 loops=1)
Buffers: shared hit=3
Issues: triggers
At the end of the query plan
Total time across calls
Check foreign keys indexed
Before triggers vs after triggers
Planning Time: 0.227 ms
Trigger: RI_ConstraintTrigger_a_12345 on table
time=83129.491 calls=2222623
Execution Time: 87645.739 ms
Trigger proportion:
83129.491/(0.227 + 87645.739) = 95%
Summary: check the arithmetic
Watch out for loops and threads
Watch out for CTEs
Tools can help, if in doubt check two
Summary: keep rarer issues in mind
Check the end section first
Also look out for filters, rechecks, lossy
blocks, amount of data
Tools, mailing lists, and communities can help
Thank you! Any questions?
michael@pgmustard.com
michristofides
Further reading:
* flame-explain.com/docs/general/quirk-correction
* pgmustard.com/docs/explain
* wiki.postgresql.org/wiki/Slow_Query_Questions

Más contenido relacionado

La actualidad más candente

Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
Accumulo Summit
 
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
Accumulo Summit
 

La actualidad más candente (20)

Creating and Using the Flux SQL Datasource | Katy Farmer | InfluxData
Creating and Using the Flux SQL Datasource | Katy Farmer | InfluxData Creating and Using the Flux SQL Datasource | Katy Farmer | InfluxData
Creating and Using the Flux SQL Datasource | Katy Farmer | InfluxData
 
A Fast Intro to Fast Query with ClickHouse, by Robert Hodges
A Fast Intro to Fast Query with ClickHouse, by Robert HodgesA Fast Intro to Fast Query with ClickHouse, by Robert Hodges
A Fast Intro to Fast Query with ClickHouse, by Robert Hodges
 
Taming GC Pauses for Humongous Java Heaps in Spark Graph Computing-(Eric Kacz...
Taming GC Pauses for Humongous Java Heaps in Spark Graph Computing-(Eric Kacz...Taming GC Pauses for Humongous Java Heaps in Spark Graph Computing-(Eric Kacz...
Taming GC Pauses for Humongous Java Heaps in Spark Graph Computing-(Eric Kacz...
 
Our Story With ClickHouse at seo.do
Our Story With ClickHouse at seo.doOur Story With ClickHouse at seo.do
Our Story With ClickHouse at seo.do
 
Obtaining the Perfect Smoke By Monitoring Your BBQ with InfluxDB and Telegraf
Obtaining the Perfect Smoke By Monitoring Your BBQ with InfluxDB and TelegrafObtaining the Perfect Smoke By Monitoring Your BBQ with InfluxDB and Telegraf
Obtaining the Perfect Smoke By Monitoring Your BBQ with InfluxDB and Telegraf
 
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
Accumulo Summit 2015: Performance Models for Apache Accumulo: The Heavy Tail ...
 
Kapacitor - Real Time Data Processing Engine
Kapacitor - Real Time Data Processing EngineKapacitor - Real Time Data Processing Engine
Kapacitor - Real Time Data Processing Engine
 
On heap cache vs off-heap cache
On heap cache vs off-heap cacheOn heap cache vs off-heap cache
On heap cache vs off-heap cache
 
Postgres Performance for Humans
Postgres Performance for HumansPostgres Performance for Humans
Postgres Performance for Humans
 
Supercharge your Analytics with ClickHouse, v.2. By Vadim Tkachenko
Supercharge your Analytics with ClickHouse, v.2. By Vadim TkachenkoSupercharge your Analytics with ClickHouse, v.2. By Vadim Tkachenko
Supercharge your Analytics with ClickHouse, v.2. By Vadim Tkachenko
 
InfluxData Platform Future and Vision
InfluxData Platform Future and VisionInfluxData Platform Future and Vision
InfluxData Platform Future and Vision
 
[241]large scale search with polysemous codes
[241]large scale search with polysemous codes[241]large scale search with polysemous codes
[241]large scale search with polysemous codes
 
codecentric AG: Using Cassandra and Clojure for Data Crunching backends
codecentric AG: Using Cassandra and Clojure for Data Crunching backendscodecentric AG: Using Cassandra and Clojure for Data Crunching backends
codecentric AG: Using Cassandra and Clojure for Data Crunching backends
 
Distributed Computing on PostgreSQL | PGConf EU 2017 | Marco Slot
Distributed Computing on PostgreSQL | PGConf EU 2017 | Marco SlotDistributed Computing on PostgreSQL | PGConf EU 2017 | Marco Slot
Distributed Computing on PostgreSQL | PGConf EU 2017 | Marco Slot
 
ClickHouse Introduction by Alexander Zaitsev, Altinity CTO
ClickHouse Introduction by Alexander Zaitsev, Altinity CTOClickHouse Introduction by Alexander Zaitsev, Altinity CTO
ClickHouse Introduction by Alexander Zaitsev, Altinity CTO
 
Adventures in Observability: How in-house ClickHouse deployment enabled Inst...
 Adventures in Observability: How in-house ClickHouse deployment enabled Inst... Adventures in Observability: How in-house ClickHouse deployment enabled Inst...
Adventures in Observability: How in-house ClickHouse deployment enabled Inst...
 
Hadoop Query Performance Smackdown
Hadoop Query Performance SmackdownHadoop Query Performance Smackdown
Hadoop Query Performance Smackdown
 
Data correlation using PySpark and HDFS
Data correlation using PySpark and HDFSData correlation using PySpark and HDFS
Data correlation using PySpark and HDFS
 
R and cpp
R and cppR and cpp
R and cpp
 
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
Accumulo Summit 2015: Ferrari on a Bumpy Road: Shock Absorbers to Smooth Out ...
 

Similar a A Deeper Dive into EXPLAIN

MongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
MongoDB Chicago - MapReduce, Geospatial, & Other Cool FeaturesMongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
MongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
ajhannan
 

Similar a A Deeper Dive into EXPLAIN (20)

Dive into EXPLAIN - PostgreSql
Dive into EXPLAIN  - PostgreSqlDive into EXPLAIN  - PostgreSql
Dive into EXPLAIN - PostgreSql
 
Why learn Internals?
Why learn Internals?Why learn Internals?
Why learn Internals?
 
SQL: Query optimization in practice
SQL: Query optimization in practiceSQL: Query optimization in practice
SQL: Query optimization in practice
 
Becoming a better developer with EXPLAIN
Becoming a better developer with EXPLAINBecoming a better developer with EXPLAIN
Becoming a better developer with EXPLAIN
 
Gpu programming with java
Gpu programming with javaGpu programming with java
Gpu programming with java
 
JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course
JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course
JDD 2016 - Tomasz Borek - DB for next project? Why, Postgres, of course
 
Quick Wins
Quick WinsQuick Wins
Quick Wins
 
Three steps to untangle data traffic jams
Three steps to untangle data traffic jamsThree steps to untangle data traffic jams
Three steps to untangle data traffic jams
 
Golang in TiDB (GopherChina 2017)
Golang in TiDB  (GopherChina 2017)Golang in TiDB  (GopherChina 2017)
Golang in TiDB (GopherChina 2017)
 
Overview of the Hive Stinger Initiative
Overview of the Hive Stinger InitiativeOverview of the Hive Stinger Initiative
Overview of the Hive Stinger Initiative
 
Writing Faster Python 3
Writing Faster Python 3Writing Faster Python 3
Writing Faster Python 3
 
GALE: Geometric active learning for Search-Based Software Engineering
GALE: Geometric active learning for Search-Based Software EngineeringGALE: Geometric active learning for Search-Based Software Engineering
GALE: Geometric active learning for Search-Based Software Engineering
 
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
 
Conf orm - explain
Conf orm - explainConf orm - explain
Conf orm - explain
 
AA_Unit 1_part-I.pptx
AA_Unit 1_part-I.pptxAA_Unit 1_part-I.pptx
AA_Unit 1_part-I.pptx
 
Mathemetics module
Mathemetics moduleMathemetics module
Mathemetics module
 
Performance Tuning and Optimization
Performance Tuning and OptimizationPerformance Tuning and Optimization
Performance Tuning and Optimization
 
PostgreSQL: Advanced indexing
PostgreSQL: Advanced indexingPostgreSQL: Advanced indexing
PostgreSQL: Advanced indexing
 
Parallel Computing - Lec 4
Parallel Computing - Lec 4Parallel Computing - Lec 4
Parallel Computing - Lec 4
 
MongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
MongoDB Chicago - MapReduce, Geospatial, & Other Cool FeaturesMongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
MongoDB Chicago - MapReduce, Geospatial, & Other Cool Features
 

Más de EDB

EFM Office Hours - APJ - July 29, 2021
EFM Office Hours - APJ - July 29, 2021EFM Office Hours - APJ - July 29, 2021
EFM Office Hours - APJ - July 29, 2021
EDB
 
Is There Anything PgBouncer Can’t Do?
Is There Anything PgBouncer Can’t Do?Is There Anything PgBouncer Can’t Do?
Is There Anything PgBouncer Can’t Do?
EDB
 

Más de EDB (20)

Cloud Migration Paths: Kubernetes, IaaS, or DBaaS
Cloud Migration Paths: Kubernetes, IaaS, or DBaaSCloud Migration Paths: Kubernetes, IaaS, or DBaaS
Cloud Migration Paths: Kubernetes, IaaS, or DBaaS
 
Die 10 besten PostgreSQL-Replikationsstrategien für Ihr Unternehmen
Die 10 besten PostgreSQL-Replikationsstrategien für Ihr UnternehmenDie 10 besten PostgreSQL-Replikationsstrategien für Ihr Unternehmen
Die 10 besten PostgreSQL-Replikationsstrategien für Ihr Unternehmen
 
Migre sus bases de datos Oracle a la nube
Migre sus bases de datos Oracle a la nube Migre sus bases de datos Oracle a la nube
Migre sus bases de datos Oracle a la nube
 
EFM Office Hours - APJ - July 29, 2021
EFM Office Hours - APJ - July 29, 2021EFM Office Hours - APJ - July 29, 2021
EFM Office Hours - APJ - July 29, 2021
 
Benchmarking Cloud Native PostgreSQL
Benchmarking Cloud Native PostgreSQLBenchmarking Cloud Native PostgreSQL
Benchmarking Cloud Native PostgreSQL
 
Las Variaciones de la Replicación de PostgreSQL
Las Variaciones de la Replicación de PostgreSQLLas Variaciones de la Replicación de PostgreSQL
Las Variaciones de la Replicación de PostgreSQL
 
NoSQL and Spatial Database Capabilities using PostgreSQL
NoSQL and Spatial Database Capabilities using PostgreSQLNoSQL and Spatial Database Capabilities using PostgreSQL
NoSQL and Spatial Database Capabilities using PostgreSQL
 
Is There Anything PgBouncer Can’t Do?
Is There Anything PgBouncer Can’t Do?Is There Anything PgBouncer Can’t Do?
Is There Anything PgBouncer Can’t Do?
 
Data Analysis with TensorFlow in PostgreSQL
Data Analysis with TensorFlow in PostgreSQLData Analysis with TensorFlow in PostgreSQL
Data Analysis with TensorFlow in PostgreSQL
 
Practical Partitioning in Production with Postgres
Practical Partitioning in Production with PostgresPractical Partitioning in Production with Postgres
Practical Partitioning in Production with Postgres
 
IOT with PostgreSQL
IOT with PostgreSQLIOT with PostgreSQL
IOT with PostgreSQL
 
A Journey from Oracle to PostgreSQL
A Journey from Oracle to PostgreSQLA Journey from Oracle to PostgreSQL
A Journey from Oracle to PostgreSQL
 
Psql is awesome!
Psql is awesome!Psql is awesome!
Psql is awesome!
 
EDB 13 - New Enhancements for Security and Usability - APJ
EDB 13 - New Enhancements for Security and Usability - APJEDB 13 - New Enhancements for Security and Usability - APJ
EDB 13 - New Enhancements for Security and Usability - APJ
 
Comment sauvegarder correctement vos données
Comment sauvegarder correctement vos donnéesComment sauvegarder correctement vos données
Comment sauvegarder correctement vos données
 
Cloud Native PostgreSQL - Italiano
Cloud Native PostgreSQL - ItalianoCloud Native PostgreSQL - Italiano
Cloud Native PostgreSQL - Italiano
 
New enhancements for security and usability in EDB 13
New enhancements for security and usability in EDB 13New enhancements for security and usability in EDB 13
New enhancements for security and usability in EDB 13
 
Best Practices in Security with PostgreSQL
Best Practices in Security with PostgreSQLBest Practices in Security with PostgreSQL
Best Practices in Security with PostgreSQL
 
Cloud Native PostgreSQL - APJ
Cloud Native PostgreSQL - APJCloud Native PostgreSQL - APJ
Cloud Native PostgreSQL - APJ
 
Best Practices in Security with PostgreSQL
Best Practices in Security with PostgreSQLBest Practices in Security with PostgreSQL
Best Practices in Security with PostgreSQL
 

Último

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 

A Deeper Dive into EXPLAIN

  • 1. A deeper dive into EXPLAIN Michael Christofides
  • 2. Hi, I’m Michael Half of the team behind pgMustard Spent a lot of time looking into EXPLAIN Background: product management, database tools pgmustard.com/docs/explain michael@pgmustard.com michristofides
  • 3. Picking up from other EXPLAIN talks Not the basics* 1) Some of the less intuitive arithmetic 2) Some less well covered issues * postgresql.org/docs/current/performance-tips thoughtbot: reading EXPLAIN ANALYZE YouTube: Josh Berkus Explaining EXPLAIN
  • 4. Picking up from other EXPLAIN talks Not the basics* 1) Arithmetic: why is this query slow? 2) Issues: what can we do about it? * postgresql.org/docs/current/performance-tips thoughtbot: reading EXPLAIN ANALYZE YouTube: Josh Berkus Explaining EXPLAIN
  • 5. Arithmetic: loops Many of the stats are a per-loop average This includes costs, rows, timings Watch out for rounding, especially to 0 rows
  • 6. Disclaimer: heavily doctored plans ahead, inaccuracies likely.
  • 7. Nested Loop (cost=0.84..209.82 rows=16 width=11) (actual time=0.076..0.368 rows=86 loops=1) -> Index Only Scan using a on b (cost=0.42..4.58 rows=9 width=4) (actual time=0.013..0.019 rows=9 loops=1) -> Index Scan using x on y (cost=0.42..22.73 rows=7 width=15) (actual time=0.012..0.030 rows=10 loops=9) Nested Loop: 86 rows Index Scan: 9 * 10 = 90 rows (Rounding not too bad here)
  • 8. Arithmetic: threads Costs, rows, and timings are also per-thread Shown as loops Threads = workers + 1 Tip: use VERBOSE <- the leader
  • 9. Parallel Seq Scan on table (cost=0.00..6772.21 rows=79521 width=22) (actual time=0.090..71.866 rows=63617 loops=3) Output: column1, column2, column3 Worker 0: actual time=0.111..66.325 rows=56225 loops=1 Worker 1: actual time=0.138..66.027 rows=58792 loops=1 Seq Scan: 63617 * 3 = 190851 rows Leader: 190851 - 58792 - 56225 = 75834 rows
  • 10. Arithmetic: buffers Buffer stats are a total, not per-loop They are inclusive of children
  • 11. Nested Loop (... loops=1) Buffers: shared hit=105 -> Index Only Scan using a on b (... loops=1) Buffers: shared hit=4 -> Index Scan using x on y (... loops=9) Buffers: shared hit=101 Nested Loop buffers: 105 - (101 + 4) = 0 blocks
  • 12. Arithmetic: timings Per-loop, per-thread Inclusive of children Calculating per-node (exclusive) times can get tricky, even for tools
  • 13. Nested Loop (cost=0.84..209.82 rows=16 width=11) (actual time=0.076..0.368 rows=86 loops=1) -> Index Only Scan using a on b (cost=0.42..4.58 rows=9 width=4) (actual time=0.013..0.019 rows=9 loops=1) -> Index Scan using x on y (cost=0.42..22.73 rows=7 width=15) (actual time=0.012..0.030 rows=10 loops=9) Index Scan: 0.030 * 9 = 0.27 ms Nested Loop: 0.368 - 0.27 - 0.019 = 0.079 ms
  • 14. WITH init AS ( SELECT * FROM pg_sleep_for('100ms') UNION ALL SELECT * FROM pg_sleep_for('200ms') ) (SELECT * FROM init LIMIT 1) UNION ALL (SELECT * FROM init); Credit @felixge
  • 15. Append (actual time=100.359.. 300.688 … ) CTE init -> Append (actual time=100.334.. 300.652 … ) -> Function Scan (actual time=100.333.. 100.335 … ) -> Function Scan (actual time=200.310.. 200.312 … ) -> Limit (actual time=100.358.. 100.359 … ) -> CTE Scan a (actual time=100.355..100.356 … ) -> CTE Scan b (actual time=0.001.. 200.322 … ) Execution Time: 300.789 ms Further reading: flame-explain.com/docs/general/quirk-correction Some double-counting in this case.
  • 16. Arithmetic: tools can help eg explain.depesz.com explain.dalibo.com flame-explain.com pgmustard.com <- fellow calculations nerd <- 👋
  • 17. Issues: let’s skip the basics Seq Scans with large filters Bad row estimates Sorts and Hashes on disk
  • 18. Issues: inefficient index scans Looks out for lots of rows being filtered Filters are per-loop So again, watch out for rounding
  • 19. -> Index Scan using x on y (cost=0.42..302502.05 rows=1708602 width=125) (actual time=172810.219..173876.540 rows=1000 loops=1) Index Cond: (id = another_id) Filter: (status = 1) Rows Removed by Filter: 3125626 Index efficiency: 1000/(1000+3125626) = 0.03% Watch out for high loops
  • 20. Issues: lossy bitmap scans When bitmap would otherwise exceed work_mem Point to a block rather than a row (Tuple Id) Lossy blocks are a total (ie not per-loop)
  • 21. -> Bitmap Heap Scan on table (cost=49153.29..4069724.27 rows=3105598 width=1106) (actual time=591.928..56472.895 rows=3853272 loops=1) Recheck Cond: (something > something_else) Rows Removed by Index Recheck: 5905323 Heap Blocks: exact=14280 lossy=1951048 Lossy blocks: 1951048/(1951048+14280) = 99% Extra rows read: 5.9 million
  • 22. Issues: lots of data read Requires BUFFERS Lots of data being read for the amount returned Can be a sign of bloat Default block size: 8kB
  • 23. -> Index Scan using x on y (cost=0.57..2.57 rows=1 width=8) (actual time=0.064..0.064 rows=1 loops=256753) Index Cond: (id = another_id) Filter: (status = 1) Buffers: shared hit=1146405 read=110636 Caveats: width estimated, rows rounded Data read: (1146405 + 110636) * 8kB = 10GB Data returned: 1 * 256753 * 8 bytes = 2MB
  • 24. Issues: planning time At the end of the query plan Can be planning related: eg joins, partitions But other things too: eg extensions, locks Warning: not included in auto_explain
  • 25. (...) Planning Time: 27.844 ms Execution Time: 11.162 ms Planning proportion: 27.844/(27.844 + 11.162) = 71%
  • 26. Issues: Just In Time compilation At the end of the query plan Included in execution time On by default in PostgreSQL 12 and 13 Start-up time can be a tell-tale
  • 27. Planning Time: 9.138 ms JIT: Functions: 277 Options: Inlining true, Optimization true, Expressions true, Deforming true Timing: Generation 31.602 ms, Inlining 253.114 ms, Optimization 1498.268 ms, Emission 913.945 ms, Total 2696.929 ms Execution Time: 5194.851 ms JIT proportion: 2696.929/(9.138 + 5194.851) = 52%
  • 28. Very suspicious actual start-up time from a JIT dominated plan. -> Seq Scan on table (cost=0.00..3.57 rows=72 width=8) (actual time=2262.312..2262.343 rows=54 loops=1) Buffers: shared hit=3
  • 29. Issues: triggers At the end of the query plan Total time across calls Check foreign keys indexed Before triggers vs after triggers
  • 30. Planning Time: 0.227 ms Trigger: RI_ConstraintTrigger_a_12345 on table time=83129.491 calls=2222623 Execution Time: 87645.739 ms Trigger proportion: 83129.491/(0.227 + 87645.739) = 95%
  • 31. Summary: check the arithmetic Watch out for loops and threads Watch out for CTEs Tools can help, if in doubt check two
  • 32. Summary: keep rarer issues in mind Check the end section first Also look out for filters, rechecks, lossy blocks, amount of data Tools, mailing lists, and communities can help
  • 33. Thank you! Any questions? michael@pgmustard.com michristofides Further reading: * flame-explain.com/docs/general/quirk-correction * pgmustard.com/docs/explain * wiki.postgresql.org/wiki/Slow_Query_Questions