2016-05-26 14 views
1

Wir haben Postgres basierend Nur Lesen Datenbank. Da haben wir 52 Tabellen unter einem Schema.So erhalten Sie die Gesamtzahl der Zeilen und Max (Zeitstempel) Spalte in Auswahlliste für alle Tabellen in bestimmten Schema

Wir versuchen Zeile Zeile und Max (Zeitstempel) Spalte für alle Tabellen unter einem Schema auszugeben.

Umwelt ist:

PostgreSQL 8.2.15 (Greenplum Database 4.2.0 build 1) (HAWQ 1.3.0.2 14421 bauen) auf x86_64-unknown-linux-gnu, zusammengestellt von GCC gcc (GCC) 4.4.2 kompiliert

wir haben versucht, auf:

SELECT 
    nspname AS schemaname,relname,reltuples,max(time) 
FROM pg_class C 
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) 
WHERE 
    nspname NOT IN ('pg_catalog', 'information_schema') AND 
    relkind='r' 
ORDER BY reltuples DESC; 

In dieser Abfrage, wir haben die Zeilenanzahl Spalte, aber immer noch max (Zeitstempel) für alle Tabelle nicht erreicht wird.

Jede Hilfe wird sehr geschätzt werden?

+0

Hallo vickps Welches Zeitstempelformat verwendest du mit Eg Zeit mit oder ohne Zeitzone? – pnorton

+0

Zeitstempel ohne Zeitzone – NEO

Antwort

4

Sie greifen mit dieser Abfrage auf Datenbankstatistiken zu, die nicht zu 100% genau sind und abhängig von Ihren statistischen Erfassungsprozessen möglicherweise fehlen oder veraltet sind.

Um die Zeilenanzahl für eine Liste von Tabellen zu erhalten, müssen Sie jede dieser Tabellen scannen. Sie können jedoch pg_relation_size() verwenden, um eine Vorstellung von der Tabellengröße in Bytes zu erhalten, und diese Funktion erfordert nicht das Scannen der Tabelle.

Wenn Ihre Tabelle Liste statisch ist, können Sie mit einer Abfrage wie folgt wegkommen:

select 'table1', count(*), max(time) from table1 
union all 
select 'table2', count(*), max(time) from table2 
union all 
... 
select 'table52', count(*), max(time) from table52; 

Diese Lösung nicht flexibel ist, als ob Tabellenliste geändert hat, können Sie Ihre Abfrage neu schreiben müssen.

Zweite Option ist diese Abfrage zu generieren und manuell ausführen:

select string_agg(query, ' union all ') as query 
    from (
     select 'select ''' || n.nspname || '.' || c.relname || ''', count(*), max(time) from ' || n.nspname || '.' || c.relname as query 
      from pg_namespace as n, pg_class as c 
      where n.oid = c.relnamespace 
       and n.nspname = 'my_schema' 
     ) as q; 

Dies ist flexibler, aber die zweite Abfrage sollte manuell ausgeführt werden.

Und schließlich die letzte Option - eine Funktion für das Tun so zu schreiben:

create or replace function table_sizes (schemaname varchar) returns setof record as $BODY$ 
declare 
    r record; 
    t varchar; 
begin 
    for t in execute $$ 
     select n.nspname || '.' || c.relname 
      from pg_namespace as n, pg_class as c 
      where n.oid = c.relnamespace 
       and c.relkind = 'r' 
       and n.nspname = '$$ || schemaname || $$'$$ 
    loop 
     execute 'select ''' || t || '''::varchar, count(*), max(time) from ' || t 
      into r; 
     return next r; 
    end loop; 
    return; 
end; 
$BODY$ language plpgsql volatile; 

select * from table_sizes('public') t(tablename varchar, rowcount bigint, maxtime time); 
+0

verwenden, wenn ich die Funktion hier ausführe.Folgendes erhalten :: prod = # select * aus table_sizes ('schemaname') t (Tabellenname varchar, rowcount bigint, maxtime Zeit); FEHLER: falscher Datensatztyp in RETURN NEXT CONTEXT: PL/pgSQL Funktion "Tabelle Größen" Zeile 14 bei der Rückkehr nächsten prod = # – NEO

+0

bedeutet dies, dass Ihre "Select" -Anweisung nicht zurückgegebenen Datentyp zurückgegeben. Was ist der Datentyp des Felds "Zeit"? Es sollte mit dem in "Select" -Abfrage – 0x0FFF

+0

Timestamp ohne Zeitzone – NEO

1

Hier sind einige weitere Schritte zu tun:

In psql tun unten Schritte

\o count_per_schema.sql 
select 'select count(*)as '||c.relname||', max(time) from ' || n.nspname || '.' || c.relname || ';' as " " from pg_namespace as n, pg_class as c where n.oid = c.relnamespace and c.relkind='r' and n.nspname = 'schema_name'; 
\o 
\i count_per_schema.sql 

\o wird Redirect Ergebnis zu filename Sie zur Verfügung gestellt. Für Beispiel count_per_schema.sql und \i werden alle Abfragen von Datei ausgeführt.

Hier ist, was ich im Server getan habe. Ich habe max (Zeit) nicht ausgewählt.

yogesh=# \o count_per_schema.sql 
yogesh=# select 'select count(*)as '||c.relname||' from ' || n.nspname || '.' || c.relname || ';' as " " from pg_namespace as n, pg_class as c where n.oid = c.relnamespace and c.relkind='r' and n.nspname = 'public'; 
yogesh=# \o 
yogesh=# \i count_per_schema.sql 

heap1 
------- 
20000 
(1 row) 
test 
------- 
    4 
(1 row) 
users 
------- 
    0 
(1 row) 
skew_demo 
------- 
10609 
(1 row) 
+0

Vorteil davon ist, dass Sie Einträge für Tabellen löschen können, die Sie nicht möchten ** Ausgabedatei ** –