--- aliases: - explain tags: - maturity/🌱 date: 2024-06-10 --- ΠšΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово `EXPLAIN` ΠΏΠ΅Ρ€Π΅Π΄ SQL-запросом позволяСт ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ PostgreSQL **ΠΏΠ»Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚** Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ этот запрос "ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ΠΎΠΌ". Π­Ρ‚ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ для диагностики ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ шаги выполняСт Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Π³Π΄Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ·ΠΊΠΈΠ΅ мСста. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования `EXPLAIN` ```sql postgres=# EXPLAIN SELECT * FROM users WHERE id = 20; QUERY PLAN ------------------------------------------------------- Index Scan using users_pkey on users (cost=0.15..8.17 rows=1 width=72) Index Cond: (id = 20) (2 rows) ``` Π’Ρ‹Π²ΠΎΠ΄ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ. НапримСр, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ JSON: ```sql EXPLAIN (FORMAT JSON) SELECT * FROM users WHERE id = 20; ``` > [!NOTE] Analyze > `EXPLAIN` Π½Π΅ выполняСт сам запрос, поэтому Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ. Для Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ Π°Π½Π°Π»ΠΈΠ·Π° ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ слово `ANALYZE`, ΠΈ Ρ‚ΠΎΠ³Π΄Π° `EXPLAIN` Ρ‚Π°ΠΊΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ запрос. ## Π‘Ρ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ выполнСния запроса (cost) PostgreSQL ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ условныС Π΅Π΄ΠΈΠ½ΠΈΡ†Ρ‹ для обозначСния стоимости выполнСния запроса β€” `cost`. Один `cost` ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ соотвСтствуСт Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, Π·Π°Ρ‚Ρ€Π°Ρ‡Π΅Π½Π½ΠΎΠΌΡƒ Π½Π° ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ… Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ 8 ΠΊΠΈΠ»ΠΎΠ±Π°ΠΉΡ‚ ΠΏΡ€ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌ сканировании (Seq Scan). Часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π΄Π²Π° значСния `cost`: - **ΠŸΠ΅Ρ€Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅**: ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ Π΄ΠΎ Π½Π°Ρ‡Π°Π»Π° получСния ΠΏΠ΅Ρ€Π²Ρ‹Ρ… Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ². - **Π’Ρ‚ΠΎΡ€ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅**: полная ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ выполнСния запроса. Если ΠΎΡ†Π΅Π½ΠΎΡ‡Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ `rows` слишком Π½ΠΈΠ·ΠΊΠΎΠ΅ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с фактичСским количСством строк, это ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ·Π½Π°Ρ‡Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ статистика Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ устарСла. Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ `ANALYZE` для обновлСния статистики ΠΈ ΡƒΠ»ΡƒΡ‡ΡˆΠ΅Π½ΠΈΡ качСства планирования запросов. ## Π’ΠΈΠ΄Ρ‹ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΎΠ² ΠΏΠΎ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ ΠΈ индСксу - **Seq Scan**: ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ просмотр всСй Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹. Π­Ρ‚ΠΎ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΈ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π½Π΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»Π΅Π½. РСшСниС β€” Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ [[../ИндСкс Π² Π‘Π”|индСкс]], Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΡΠΊΠΎΡ€ΠΈΡ‚ΡŒ Π²Ρ‹Π±ΠΎΡ€ΠΊΡƒ Π΄Π°Π½Π½Ρ‹Ρ…. - **Index Scan**: использованиС [[../ИндСкс Π² Π‘Π”|индСкса]] для просмотра Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹. - **Index Only Scan**: использованиС [[../ΠŸΠΎΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ индСкс|ΠΏΠΎΠΊΡ€Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ индСкса]], ΠΊΠΎΠ³Π΄Π° всС Π½ΡƒΠΆΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ находятся Π² индСксС ΠΈ Π½Π΅ трСбуСтся Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ доступа ΠΊ Ρ‚Π°Π±Π»ΠΈΡ†Π΅. - **Bitmap Heap Scan**: оптимизация с использованиСм Π±ΠΈΡ‚ΠΎΠ²Ρ‹Ρ… ΠΊΠ°Ρ€Ρ‚ для поиска. Π‘Π½Π°Ρ‡Π°Π»Π° строятся Π±ΠΈΡ‚ΠΎΠ²Ρ‹Π΅ ΠΊΠ°Ρ€Ρ‚Ρ‹ с использованиСм Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… индСксов, Π·Π°Ρ‚Π΅ΠΌ ΠΎΠ½ΠΈ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΡƒΡŽΡ‚ΡΡ. - **Foreign Scan**: сканированиС Π΄Π°Π½Π½Ρ‹Ρ… Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ сСрвСрС, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ΅ ΠΏΡ€ΠΈ [[Π¨Π°Ρ€Π΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² PostgreSQL|ΡˆΠ°Ρ€Π΄ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ]]. *** ## ΠœΠ΅Ρ‚Π° информация **ΠžΠ±Π»Π°ΡΡ‚ΡŒ**:: [[../../../meta/zero/00 PostgreSQL|00 PostgreSQL]] **Π ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ**:: [[ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡ SQL запросов Π² PostgreSQL]] **Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ**:: **Автор**:: **Π‘ΠΎΠ·Π΄Π°Π½Π°**:: [[2024-01-29]] ### Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹ - ### Π”ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ Π·Π°ΠΌΠ΅Ρ‚ΠΊΠΈ