2012-04-04 5 views
5

Następująca kwerenda Postgres SQL będzie lista wszystkich tabel ze wszystkich schematów i ich wielkości i wielkości indeksu. Jeśli tabela jest po prostu tabelą indeksu, pojawi się jako indeks 100%.Uproszczenie zapytania Postgres SQL dla aukcji Tabela i indeks?

SELECT schema, 
     name, 
     pg_size_pretty(CASE WHEN is_index THEN 0 ELSE s  END) AS size, 
     pg_size_pretty(CASE WHEN is_index THEN s ELSE st - s END) AS index, 
     CASE WHEN st = 0 THEN 0 
      WHEN is_index THEN 100 
          ELSE 100 - ((s*100)/st) END || '%' as ratio, 
     pg_size_pretty(st) as total 
    FROM (SELECT *, 
       st = s AS is_index 
      FROM (SELECT nspname as schema, 
         relname as name, 
         pg_relation_size(nspname || '.' || relname) as s, 
         pg_total_relation_size(nspname || '.' || relname) as st 
        FROM pg_class 
      JOIN pg_namespace ON (relnamespace = pg_namespace.oid)) AS p)               
    AS pp                 
ORDER BY st DESC LIMIT 30; 

To daje następujące wyniki:

schema   |   name   | size | index | ratio | total 
----------------+------------------------+---------+---------+-------+--------- 
public   | conf     | 4072 kB | 4360 kB | 52% | 8432 kB 
archive  | product_param   | 4048 kB | 3968 kB | 50% | 8016 kB             
public   | conf_pkey    | 0 bytes | 4320 kB | 100% | 4320 kB 
archive  | product_value   | 1568 kB | 1136 kB | 43% | 2704 kB 
public   | param_mapping   | 1472 kB | 832 kB | 37% | 2304 kB 
archive  | supplie_price   | 944 kB | 896 kB | 49% | 1840 kB 
public   | product_param_param_id | 0 bytes | 1552 kB | 100% | 1552 kB 
archive  | product_param_id  | 0 bytes | 1536 kB | 100% | 1536 kB 

Doszedłem do punktu, w którym nie widzę lasu dla wszystkich drzew, a to zaczyna się trochę nieporęczny.

Zastanawiam się, czy jest coś w tym, że można uprościć lub zwolnionych? Kolumny niekoniecznie muszą pozostać takie same, jeśli zapytanie może być znacznie prostsze.

+0

Zobacz także http://stackoverflow.com/questions/2596624/how-do-you-find-the-dize-size-of-a-postgres-postgresql- table-and-its-indexes. – Vadzim

Odpowiedz

3

uzyskać porównywalne wyniki (z innego formatowania) z tego zapytania:

select 
    nspname as schema, 
    relname as name, 
    pg_relation_size(pg_class.oid) as size, 
    pg_indexes_size(pg_class.oid) as index, 
    pg_total_relation_size(pg_class.oid) as total, 
    100 * case when relkind = 'i' then pg_relation_size(pg_class.oid) 
            else pg_indexes_size(pg_class.oid) end 
     /pg_total_relation_size(pg_class.oid) as i_ratio 
from 
    pg_class 
    join pg_namespace on relnamespace = pg_namespace.oid 
order by 5 desc 
+0

Jednak bez śladu drukowania. :-( –

+0

@AdamLindberg Możesz dość ładnie wydrukować zapytanie: Moim kluczowym punktem badawczym było uproszczenie łączeń i podkwerendy .. –

+0

Jedynym problemem jest zamawianie po 'pg_size_pretty (...)' zamówieniach w oparciu o wartość łańcucha o ładnym rozmiarze, czyli 96 Kb> 960 Kb. –

0

Przede wszystkim dlatego, aby nie stosować współczynniki CTE będą one kodować nieco bardziej czytelny. Wtedy nie zwracają is_index więc wydaje się być redundunt

with p as (
SELECT nspname as schema, 
     relname as name, 
     pg_relation_size(nspname || '.' || relname) as s, 
     pg_total_relation_size(nspname || '.' || relname) as st 
    FROM pg_class 
     JOIN pg_namespace 
      ON (relnamespace = pg_namespace.oid) 
), 
pp as (
SELECT *, 
     case when st = s then 0 else s end as size, 
     case when st = s then s else st-s end as index 

    FROM p 
) 
select schema, 
     name, 
     pg_size_pretty(size) as size,   
     pg_size_pretty(index) as index, 
     (case st 
      when 0 then 0 
      else index*100/st 
     end) || '%' ratio, 
     st total 
from pp 
order by st desc limit 30; 
+0

To naprawdę nie jest prostsze ani krótsze, IMO. –

+0

Może masz rację, ale wydaje się być łatwiejsze do zrozumienia. Zmieniłem go trochę więcej. – quzary

1

Wszystko co naprawdę chcesz zrobić, to zwrócić uwagę, że odpowiedź quzary powinien być używany oid oraz nie tworząc ciągi, które nie dostać analizowany powrotem do OID-tych.

Teraz mam napisać odpowiedni wpis (być może jest to punkt zatrzymania początkujących od komentowania?) Oto kolejny czyszczone i prettied się wersja:

WITH p AS (
    SELECT n.nspname AS schema, 
     c.relname AS name, 
     pg_relation_size(c.oid) AS s, 
     pg_total_relation_size(c.oid) AS st 
    FROM pg_class c, pg_namespace n 
    WHERE c.relnamespace = n.oid 
) 
SELECT schema, name, 
    pg_size_pretty(s) AS size,   
    pg_size_pretty(st - s) AS index, 
    (100.0 * s/NULLIF(st, 0))::numeric(10,1) AS "% data of total", 
    st AS total 
FROM p 
ORDER BY st DESC 
LIMIT 30; 

pamiętać, że może to być przydatne, aby dodać w następującej linii:

AND c.relkind = 'r' 

w klauzuli pWHERE. Ogranicza to to tylko do relacji/tabel i czyni kod przydatnym do ogólnego podsumowania rozmiarów tabel.

0

I nie zapominaj, że pg_relation_size i pg_total_relation_size są niewrażliwe na wielkość liter!

pg_relation_size(nspname || '.' || relname) 

rzeczywiście powinny być:

pg_relation_size('"' || nspname || '.' || relname || '"') 

więc działa z górnych przypadkach zbyt. (Trochę mi to zajęło, żeby to wymyślić)