PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Какво точно обяснява PostgreSQL?

Частта, която винаги намирах за объркваща, е началната цена спрямо общата цена. Гуглям това всеки път, когато забравя за него, което ме връща тук, което не обяснява разликата, поради което пиша този отговор. Това е, което почерпих от Postgres EXPLAIN документация, обяснено, както го разбирам.

Ето пример от приложение, което управлява форум:

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)

Ето графичното обяснение от PgAdmin:

(Когато използвате PgAdmin, можете да насочите мишката си към компонент, за да прочетете подробностите за разходите.)

Цената е представена като кортеж, напр. цената на LIMIT е cost=0.00..3.39 и разходите за последователно сканиране на post е cost=0.00..15629.12 . Първото число в кортежа е началната цена а второто число е общата цена . Тъй като използвах EXPLAIN а не EXPLAIN ANALYZE , тези разходи са приблизителни, а не действителни мерки.

  • Начална цена е сложна концепция. Това не представлява само количеството време преди този компонент започне . Той представлява времето между момента, когато компонентът започне да се изпълнява (четене на данни) и когато компонентът изведе първия си ред .
  • Обща цена е цялото време на изпълнение на компонента, от момента, когато той започне да чете данни до момента, когато завърши записването на изхода си.

Като усложнение, разходите на всеки "родителски" възел включват разходите за неговите дъщерни възли. В текстовото представяне дървото е представено с отстъп, напр. LIMIT е родителски възел и Seq Scan е негово дете. В представянето на PgAdmin стрелките сочат от дъщер към родител — посоката на потока от данни — което може да е противоинтуитивно, ако сте запознати с теорията на графите.

Документацията казва, че разходите включват всички дъщерни възли, но имайте предвид, че общата цена на родителския 3.39 е много по-малък от общата цена на неговото дете 15629.12 . Общата цена не включва, тъй като компонент като LIMIT не е необходимо да обработва целия си вход. Вижте EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2; пример в Postgres EXPLAIN документация.

В примера по-горе, времето за стартиране е нула и за двата компонента, тъй като нито един компонент не трябва да извършва никаква обработка, преди да започне да пише редове:последователно сканиране чете първия ред на таблицата и го излъчва. LIMIT чете първия си ред и след това го излъчва.

Кога един компонент трябва да извърши много обработка, преди да започне да извежда редове? Има много възможни причини, но нека разгледаме един ясен пример. Ето същата заявка от преди, но сега съдържа ORDER BY клауза:

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)

И графично:

Още веднъж, последователното сканиране на post няма начални разходи:започва да извежда редове незабавно. Но сортирането има значителна начална цена 23283.24 защото трябва да сортира цялата таблица, преди да може да изведе дори един ред . Общата цена на сортирането 23859.27 е само малко по-висока от началната цена, което отразява факта, че след като целият набор от данни е сортиран, сортираните данни могат да бъдат излъчени много бързо.

Обърнете внимание, че времето за стартиране на LIMIT 23283.24 е точно равно на времето за стартиране на сорта. Това не е защото LIMIT сам по себе си има високо време за стартиране. Той всъщност има нулево време за стартиране сам по себе си, но EXPLAIN събира всички разходи за деца за всеки родител, така че LIMIT стартовото време включва сбора от времената за стартиране на неговите дъщерни.

Този сбор на разходите може да затрудни разбирането на разходите за изпълнение на всеки отделен компонент. Например нашият LIMIT има нулево време за стартиране, но това не е очевидно на пръв поглед. Поради тази причина няколко други хора се свързаха с objasni.depesz.com, инструмент, създаден от Hubert Lubaczewski (известен още като depesz), който помага да се разбере EXPLAIN чрез — наред с други неща — изваждане на разходите за деца от разходите за родители. Той споменава някои други сложности в кратка публикация в блога за своя инструмент.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изключете предупреждението в sqlalchemy

  2. java.lang.ClassNotFoundException:org.postgresql.Driver

  3. PostgreSQL работи бавно? Съвети и трикове, за да стигнете до източника

  4. Генериране на данни и качество на хардуера

  5. Мигриране на съществуващи данни за auth.User към нов потребителски модел на Django 1.5?