2014-11-30 3 views
1

https://wiki.postgresql.org/wiki/Introduction_to_VACUUM,_ANALYZE,_EXPLAIN,_and_COUNTPostGreSQL объяснить анализ, соотношение между фактическим временем и оценкой

Я сейчас читаю эту страницу, чтобы понять, EXPLAIN ANALYZE для PostGreSQL, и я пытаюсь понять связь между затратами и оценки фактического времени.

Простой пример, приведенный на этой странице следующим образом:

-> Nested Loop (cost=5.64..14.71 rows=1 width=140) (actual time=18.983..19.481 rows=4 loops=1) 
       -> Hash Join (cost=5.64..8.82 rows=1 width=72) (actual time=18.876..19.212 rows=4 loops=1) 
       -> Index Scan using pg_class_oid_index on pg_class i (cost=0.00..5.88 rows=1 width=72) (actual time=0.051..0.055 rows=1 loops=4) 

и он говорит: "Если вы делаете математику, вы увидите, что 0,055 * 4 составляет большую часть разницы между общим временем хеш-соединения и общее время вложенного цикла (остаток, скорее всего, накладные расходы на измерение всего этого).

Я не уверен, что здесь означает «разница», и я не могу найти какую-либо разницу, которая близка к 0,055 * 4 .. Я так глуп, что просто игнорирую какой-то тривиальный результат?

Btw Я на самом деле пишу лабораторный отчет по базам данных, поэтому, как правило, если его попросят записать короткий комментарий по расчетному и фактическому времени на основе определенного результата, что я могу сказать?

это план мне нужно написать результат на:

QUERY PLAN                
--------------------------------------------------------------------------------------------------------------------------------------- 
Nested Loop (cost=39911.52..299300.41 rows=1 width=17) (actual time=4660.217..4952.328 rows=1 loops=1) 
    Join Filter: (casts.mid = movie.id) 
    Rows Removed by Join Filter: 2251735 
    -> Seq Scan on movie (cost=0.00..29721.64 rows=5542 width=21) (actual time=0.637..316.651 rows=4201 loops=1) 
     Filter: (year > 2010) 
     Rows Removed by Filter:
    -> Materialize (cost=39911.52..269080.01 rows=6 width=4) (actual time=0.307..1.014 rows=536 loops=4201) 
     -> Hash Join (cost=39911.52..269079.98 rows=6 width=4) (actual time=1288.827..4089.872 rows=536 loops=1) 
       Hash Cond: (casts.pid = actor.id) 
       -> Seq Scan on casts (cost=0.00..186246.47 rows=11445847 width=8) (actual time=0.293..1487.138 rows=11445847 loops=1) 
       -> Hash (cost=39911.51..39911.51 rows=1 width=4) (actual time=414.130..414.130 rows=1 loops=1) 
        Buckets: 1024 Batches: 1 Memory Usage: 1kB 
        -> Seq Scan on actor (cost=0.00..39911.51 rows=1 width=4) (actual time=100.175..414.125 rows=1 loops=1) 
          Filter: (((fname)::text = 'Tom'::text) AND ((lname)::text = 'Hanks'::text)) 
          Rows Removed by Filter: 1865033 
Total runtime: 4952.822 ms 
+0

Существует только взаимное отношение между стоимостью и временем. Если стоимость выше, фактическое время также может быть выше (на том же компьютере). Но стоимость - это часть _arbitrary_ unit. Его нельзя сравнивать со временем. –

ответ

1

Посмотрите на фактическое время:

 
-> Nested Loop ........ (actual time=18.983..19.481 rows=4 loops=1) 
..... 
..... 
-> Hash Join ....... (actual time=18.876..19.212 rows=4 loops=1) 
    -> Index Scan ......... (actual time=0.051..0.055 rows=1 loops=4) 


4 (петли) * 0,055 = 0,22

19,212 + 0,22 = 19,432 ==> почти 19,481 (отсутствует 0.049)


EDIT


Я думаю, что добавление индекса на actor(fname + lname),
или даже только на одной колонке actor(lname), может ускорить этот запрос драматически.

Посмотрите на это:

-> Seq Scan on actor (cost=0.00..39911.51 rows=1 width=4) (actual time=100.175..414.125 rows=1 loops=1) 
     Filter: (((fname)::text = 'Tom'::text) AND ((lname)::text = 'Hanks'::text)) 
     Rows Removed by Filter: 1865033 

PostgreSQL выполняет последовательное сканирование на actos таблице, и отфильтровывает 1865033 строк, чтобы найти только 1 строку. Общее время сканирования составляет от 100 до 414 секунд.
Одна строка может быть найдена за пару миллисекунд при использовании индекса.

+0

спасибо ... я думал 0.055 * 4 = 2.2 ........ ._. – biubiubiu3

+0

@ biubiubiu3 Я добавил комментарий к своему ответу о том, как можно повысить скорость запроса. – krokodilko

+0

Да, я действительно пробовал, что оптимальное решение дается добавлением 4 индексов к casts_pid, casts_mid, actor_lname и movie_id, которые приводят к приблизительно 4 мс .. и добавлению индекса в fname, а также не влияют на производительность. THX очень сильно – biubiubiu3

Смежные вопросы