Statistics support remaining object types that support them.

pull/3/head
Murtuza Zabuawala 2016-06-07 13:16:12 +01:00 committed by Dave Page
parent ac2612264c
commit 4ace8bb5b6
50 changed files with 870 additions and 31 deletions

View File

@ -1295,6 +1295,35 @@ It may have been removed by another user or moved to another schema.
return ajax_response(response=sql)
@check_precondition
def statistics(self, gid, sid, did, scid, fnid):
"""
Statistics
Args:
gid: Server Group Id
sid: Server Id
did: Database Id
scid: Schema Id
tid: Function/Procedure/Trigger Function Id
Returns the statistics for a particular object if fnid is specified
"""
status, res = self.conn.execute_dict(
render_template(
"/".join([self.sql_template_path, 'stats.sql']),
conn=self.conn, fnid=fnid
)
)
if not status:
return internal_server_error(errormsg=res)
return make_json_response(
data=res,
status=200
)
FunctionView.register_node_view(blueprint)

View File

@ -82,6 +82,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
collection_type: 'coll-function',
hasSQL: true,
hasDepends: true,
hasStatistics: true,
hasScriptTypes: ['create', 'select'],
parent_type: ['schema', 'catalog'],
Init: function(args) {

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -29,6 +29,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Function) {
collection_type: 'coll-procedure',
hasSQL: true,
hasDepends: true,
hasStatistics: true,
hasScriptTypes: ['create', 'exec'],
parent_type: ['schema', 'catalog'],
Init: function() {

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -25,6 +25,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
collection_type: 'coll-trigger_function',
hasSQL: true,
hasDepends: true,
hasStatistics: true,
parent_type: ['schema', 'catalog'],
Init: function(args) {
/* Avoid mulitple registration of menus */

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -0,0 +1,8 @@
SELECT
calls AS {{ conn|qtIdent(_('Number of calls')) }},
total_time AS {{ conn|qtIdent(_('Total time')) }},
self_time AS {{ conn|qtIdent(_('Self time')) }}
FROM
pg_stat_user_functions
WHERE
funcid = {{fnid}}::OID

View File

@ -688,5 +688,33 @@ class SequenceView(PGChildNodeView):
status=200
)
@check_precondition(action="stats")
def statistics(self, gid, sid, did, scid, seid):
"""
Statistics
Args:
gid: Server Group Id
sid: Server Id
did: Database Id
scid: Schema Id
seid: Sequence Id
Returns the statistics for a particular object if seid is specified
"""
status, res = self.conn.execute_dict(
render_template(
"/".join([self.template_path, 'stats.sql']),
conn=self.conn, seid=seid
)
)
if not status:
return internal_server_error(errormsg=res)
return make_json_response(
data=res,
status=200
)
SequenceView.register_node_view(blueprint)

View File

@ -24,6 +24,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
collection_type: 'coll-sequence',
hasSQL: true,
hasDepends: true,
hasStatistics: true,
parent_type: ['schema', 'catalog'],
Init: function() {
/* Avoid mulitple registration of menus */

View File

@ -0,0 +1,7 @@
SELECT
blks_read AS {{ conn|qtIdent(_('Blocks read')) }},
blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }}
FROM
pg_statio_all_sequences
WHERE
relid = {{ seid }}::OID

View File

@ -233,7 +233,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
'sql': [{'get': 'sql'}],
'msql': [{'get': 'msql'}, {'get': 'msql'}],
'stats': [{'get': 'statistics'}],
'stats': [{'get': 'statistics'}, {'get': 'statistics'}],
'dependency': [{'get': 'dependencies'}],
'dependent': [{'get': 'dependents'}],
'module.js': [{}, {}, {'get': 'module_js'}],
@ -2806,5 +2806,78 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
return ajax_response(response=sql)
@check_precondition
def statistics(self, gid, sid, did, scid, tid=None):
"""
Statistics
Args:
gid: Server Group Id
sid: Server Id
did: Database Id
scid: Schema Id
tid: Table Id
Returns the statistics for a particular table if tid is specified,
otherwise it will return statistics for all the tables in that
schema.
"""
# Fetch schema name
status, schema_name = self.conn.execute_scalar(
render_template(
"/".join([self.template_path, 'get_schema.sql']),
conn=self.conn, scid=scid
)
)
if not status:
return internal_server_error(errormsg=schema_name)
if tid is None:
status, res = self.conn.execute_dict(
render_template(
"/".join([self.template_path, 'coll_table_stats.sql']),
conn=self.conn, schema_name=schema_name
)
)
else:
# For Individual table stats
# Check if pgstattuple extension is already created?
# if created then only add extended stats
status, is_pgstattuple = self.conn.execute_scalar("""
SELECT (count(extname) > 0) AS is_pgstattuple
FROM pg_extension
WHERE extname='pgstattuple'
""")
if not status:
return internal_server_error(errormsg=is_pgstattuple)
# Fetch Table name
status, table_name = self.conn.execute_scalar(
render_template(
"/".join([self.template_path, 'get_table.sql']),
conn=self.conn, scid=scid, tid=tid
)
)
if not status:
return internal_server_error(errormsg=table_name)
status, res = self.conn.execute_dict(
render_template(
"/".join([self.template_path, 'stats.sql']),
conn=self.conn, schema_name=schema_name,
table_name=table_name,
is_pgstattuple=is_pgstattuple, tid=tid
)
)
if not status:
return internal_server_error(errormsg=res)
return make_json_response(
data=res,
status=200
)
TableView.register_node_view(blueprint)

View File

@ -902,5 +902,47 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
status=200
)
@check_precondition
def statistics(self, gid, sid, did, scid, tid, clid):
"""
Statistics
Args:
gid: Server Group Id
sid: Server Id
did: Database Id
scid: Schema Id
seid: Sequence Id
Returns the statistics for a particular object if seid is specified
"""
# Fetch column name
SQL = render_template("/".join([self.template_path,
'properties.sql']), tid=tid, clid=clid
, show_sys_objects=self.blueprint.show_system_objects)
status, res = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
data = dict(res['rows'][0])
column = data['name']
status, res = self.conn.execute_dict(
render_template(
"/".join([self.template_path, 'stats.sql']),
conn=self.conn, schema=self.schema,
table=self.table, column=column
)
)
if not status:
return internal_server_error(errormsg=res)
return make_json_response(
data=res,
status=200
)
ColumnsView.register_node_view(blueprint)

View File

@ -81,6 +81,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
}
},
hasDepends: true,
hasStatistics: true,
Init: function() {
/* Avoid mulitple registration of menus */
if (this.initialized)

View File

@ -814,6 +814,62 @@ class ExclusionConstraintView(PGChildNodeView):
except Exception as e:
return internal_server_error(errormsg=str(e))
@check_precondition
def statistics(self, gid, sid, did, scid, tid, exid):
"""
Statistics
Args:
gid: Server Group ID
sid: Server ID
did: Database ID
scid: Schema ID
tid: Table ID
cid: Exclusion constraint ID
Returns the statistics for a particular object if cid is specified
"""
# Check if pgstattuple extension is already created?
# if created then only add extended stats
status, is_pgstattuple = self.conn.execute_scalar("""
SELECT (count(extname) > 0) AS is_pgstattuple
FROM pg_extension
WHERE extname='pgstattuple'
""")
if not status:
return internal_server_error(errormsg=is_pgstattuple)
if is_pgstattuple:
# Fetch index details only if extended stats available
SQL = render_template(
"/".join([self.template_path, 'properties.sql']),
tid=tid, conn=self.conn, cid=exid)
status, result = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=result)
data = result['rows'][0]
name = data['name']
else:
name = None
status, res = self.conn.execute_dict(
render_template(
"/".join([self.template_path, 'stats.sql']),
conn=self.conn, schema=self.schema,
name=name, exid=exid, is_pgstattuple=is_pgstattuple
)
)
if not status:
return internal_server_error(errormsg=res)
return make_json_response(
data=res,
status=200
)
constraint = ConstraintRegistry(
'exclusion_constraint', ExclusionConstraintModule, ExclusionConstraintView
)

View File

@ -608,6 +608,7 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
canDrop: true,
canDropCascade: true,
hasDepends: true,
hasStatistics: true,
Init: function() {
/* Avoid multiple registration of menus */
if (this.initialized)

View File

@ -845,6 +845,62 @@ class IndexConstraintView(PGChildNodeView):
except Exception as e:
return internal_server_error(errormsg=str(e))
@check_precondition
def statistics(self, gid, sid, did, scid, tid, cid):
"""
Statistics
Args:
gid: Server Group ID
sid: Server ID
did: Database ID
scid: Schema ID
tid: Table ID
cid: Primary key/Unique constraint ID
Returns the statistics for a particular object if cid is specified
"""
# Check if pgstattuple extension is already created?
# if created then only add extended stats
status, is_pgstattuple = self.conn.execute_scalar("""
SELECT (count(extname) > 0) AS is_pgstattuple
FROM pg_extension
WHERE extname='pgstattuple'
""")
if not status:
return internal_server_error(errormsg=is_pgstattuple)
if is_pgstattuple:
# Fetch index details only if extended stats available
sql = render_template("/".join([self.template_path, 'properties.sql']),
tid=tid,
cid=cid,
constraint_type= self.constraint_type)
status, res = self.conn.execute_dict(sql)
if not status:
return internal_server_error(errormsg=res)
result = res['rows'][0]
name = result['name']
else:
name = None
status, res = self.conn.execute_dict(
render_template(
"/".join([self.template_path, 'stats.sql']),
conn=self.conn, schema=self.schema,
name=name, cid=cid, is_pgstattuple=is_pgstattuple
)
)
if not status:
return internal_server_error(errormsg=res)
return make_json_response(
data=res,
status=200
)
class PrimaryKeyConstraintView(IndexConstraintView):
node_type = 'primary_key'

View File

@ -18,6 +18,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
{% endif %}
hasSQL: true,
hasDepends: false,
hasStatistics: true,
parent_type: 'table',
canDrop: true,
canDropCascade: true,

View File

@ -200,7 +200,7 @@ class IndexesView(PGChildNodeView):
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
'sql': [{'get': 'sql'}],
'msql': [{'get': 'msql'}, {'get': 'msql'}],
'stats': [{'get': 'statistics'}],
'stats': [{'get': 'statistics'}, {'get': 'statistics'}],
'dependency': [{'get': 'dependencies'}],
'dependent': [{'get': 'dependents'}],
'module.js': [{}, {}, {'get': 'module_js'}],
@ -871,4 +871,74 @@ class IndexesView(PGChildNodeView):
status=200
)
@check_precondition
def statistics(self, gid, sid, did, scid, tid, idx=None):
"""
Statistics
Args:
gid: Server Group Id
sid: Server Id
did: Database Id
scid: Schema Id
tid: Table Id
idx: Index Id
Returns the statistics for a particular object if idx is specified
else return all indexes
"""
if idx is not None:
# Individual index
# Check if pgstattuple extension is already created?
# if created then only add extended stats
status, is_pgstattuple = self.conn.execute_scalar("""
SELECT (count(extname) > 0) AS is_pgstattuple
FROM pg_extension
WHERE extname='pgstattuple'
""")
if not status:
return internal_server_error(errormsg=is_pgstattuple)
if is_pgstattuple:
# Fetch index details only if extended stats available
SQL = render_template("/".join([self.template_path,
'properties.sql']),
tid=tid, idx=idx,
datlastsysoid=self.datlastsysoid)
status, res = self.conn.execute_dict(SQL)
if not status:
return internal_server_error(errormsg=res)
data = dict(res['rows'][0])
index = data['name']
else:
index = None
status, res = self.conn.execute_dict(
render_template(
"/".join([self.template_path, 'stats.sql']),
conn=self.conn, schema=self.schema,
index=index, idx=idx, is_pgstattuple=is_pgstattuple
)
)
else:
status, res = self.conn.execute_dict(
render_template(
"/".join([self.template_path, 'coll_stats.sql']),
conn=self.conn, schema=self.schema,
table=self.table
)
)
if not status:
return internal_server_error(errormsg=res)
return make_json_response(
data=res,
status=200
)
IndexesView.register_node_view(blueprint)

View File

@ -11,7 +11,8 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
type: 'coll-index',
sqlAlterHelp: 'sql-alterindex.html',
sqlCreateHelp: 'sql-createindex.html',
columns: ['name', 'description']
columns: ['name', 'description'],
hasStatistics: true
});
};
@ -199,6 +200,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
label: '{{ _('Index') }}',
hasSQL: true,
hasDepends: true,
hasStatistics: true,
Init: function() {
/* Avoid mulitple registration of menus */
if (this.initialized)

View File

@ -0,0 +1,14 @@
SELECT
null_frac AS {{ conn|qtIdent(_('Null fraction')) }},
avg_width AS {{ conn|qtIdent(_('Average width')) }},
n_distinct AS {{ conn|qtIdent(_('Distinct values')) }},
most_common_vals AS {{ conn|qtIdent(_('Most common values')) }},
most_common_freqs AS {{ conn|qtIdent(_('Most common frequencies')) }},
histogram_bounds AS {{ conn|qtIdent(_('Histogram bounds')) }},
correlation AS {{ conn|qtIdent(_('Correlation')) }}
FROM
pg_stats
WHERE
schemaname = {{schema|qtLiteral}}
AND tablename = {{table|qtLiteral}}
AND attname = {{column|qtLiteral}};

View File

@ -0,0 +1,14 @@
SELECT
null_frac AS {{ conn|qtIdent(_('Null fraction')) }},
avg_width AS {{ conn|qtIdent(_('Average width')) }},
n_distinct AS {{ conn|qtIdent(_('Distinct values')) }},
most_common_vals AS {{ conn|qtIdent(_('Most common values')) }},
most_common_freqs AS {{ conn|qtIdent(_('Most common frequencies')) }},
histogram_bounds AS {{ conn|qtIdent(_('Histogram bounds')) }},
correlation AS {{ conn|qtIdent(_('Correlation')) }}
FROM
pg_stats
WHERE
schemaname = {{schema|qtLiteral}}
AND tablename = {{table|qtLiteral}}
AND attname = {{column|qtLiteral}};

View File

@ -0,0 +1,28 @@
SELECT
idx_scan AS {{ conn|qtIdent(_('Index scans')) }},
idx_tup_read AS {{ conn|qtIdent(_('Index tuples read')) }},
idx_tup_fetch AS {{ conn|qtIdent(_('Index tuples fetched')) }},
idx_blks_read AS {{ conn|qtIdent(_('Index blocks read')) }},
idx_blks_hit AS {{ conn|qtIdent(_('Index blocks hit')) }},
pg_size_pretty(pg_relation_size({{ exid }}::OID)) AS {{ conn|qtIdent(_('Index size')) }}
{#=== Extended stats ===#}
{% if is_pgstattuple %}
,version AS {{ conn|qtIdent(_('Version')) }},
tree_level AS {{ conn|qtIdent(_('Tree level')) }},
pg_size_pretty(index_size) AS {{ conn|qtIdent(_('Index size')) }},
root_block_no AS {{ conn|qtIdent(_('Root block no')) }},
internal_pages AS {{ conn|qtIdent(_('Internal pages')) }},
leaf_pages AS {{ conn|qtIdent(_('Leaf pages')) }},
empty_pages AS {{ conn|qtIdent(_('Empty pages')) }},
deleted_pages AS {{ conn|qtIdent(_('Deleted pages')) }},
avg_leaf_density AS {{ conn|qtIdent(_('Average leaf density')) }},
leaf_fragmentation AS {{ conn|qtIdent(_('Leaf fragmentation')) }}
FROM
pgstatindex('{{conn|qtIdent(schema)}}.{{conn|qtIdent(name)}}'), pg_stat_all_indexes stat
{% else %}
FROM
pg_stat_all_indexes stat
{% endif %}
JOIN pg_statio_all_indexes statio ON stat.indexrelid = statio.indexrelid
JOIN pg_class cl ON cl.oid=stat.indexrelid
WHERE stat.indexrelid = {{ exid }}::OID

View File

@ -0,0 +1,28 @@
SELECT
idx_scan AS {{ conn|qtIdent(_('Index scans')) }},
idx_tup_read AS {{ conn|qtIdent(_('Index tuples read')) }},
idx_tup_fetch AS {{ conn|qtIdent(_('Index tuples fetched')) }},
idx_blks_read AS {{ conn|qtIdent(_('Index blocks read')) }},
idx_blks_hit AS {{ conn|qtIdent(_('Index blocks hit')) }},
pg_size_pretty(pg_relation_size({{ exid }}::OID)) AS {{ conn|qtIdent(_('Index size')) }}
{#=== Extended stats ===#}
{% if is_pgstattuple %}
,version AS {{ conn|qtIdent(_('Version')) }},
tree_level AS {{ conn|qtIdent(_('Tree level')) }},
pg_size_pretty(index_size) AS {{ conn|qtIdent(_('Index size')) }},
root_block_no AS {{ conn|qtIdent(_('Root block no')) }},
internal_pages AS {{ conn|qtIdent(_('Internal pages')) }},
leaf_pages AS {{ conn|qtIdent(_('Leaf pages')) }},
empty_pages AS {{ conn|qtIdent(_('Empty pages')) }},
deleted_pages AS {{ conn|qtIdent(_('Deleted pages')) }},
avg_leaf_density AS {{ conn|qtIdent(_('Average leaf density')) }},
leaf_fragmentation AS {{ conn|qtIdent(_('Leaf fragmentation')) }}
FROM
pgstatindex('{{conn|qtIdent(schema)}}.{{conn|qtIdent(name)}}'), pg_stat_all_indexes stat
{% else %}
FROM
pg_stat_all_indexes stat
{% endif %}
JOIN pg_statio_all_indexes statio ON stat.indexrelid = statio.indexrelid
JOIN pg_class cl ON cl.oid=stat.indexrelid
WHERE stat.indexrelid = {{ exid }}::OID

View File

@ -0,0 +1,17 @@
SELECT
indexrelname AS {{ conn|qtIdent(_('Index name')) }},
idx_scan AS {{ conn|qtIdent(_('Index scans')) }},
idx_tup_read AS {{ conn|qtIdent(_('Index tuples read')) }},
idx_tup_fetch AS {{ conn|qtIdent(_('Index tuples fetched')) }},
pg_size_pretty(pg_relation_size(indexrelid)) AS {{ conn|qtIdent(_('Size')) }}
FROM
pg_stat_all_indexes stat
JOIN pg_class cls ON cls.oid=indexrelid
LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0'
AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint'))
LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)
WHERE
schemaname = '{{schema}}'
AND stat.relname = '{{table}}'
AND con.contype IS NULL
ORDER BY indexrelname;

View File

@ -0,0 +1,28 @@
SELECT
idx_scan AS {{ conn|qtIdent(_('Index scans')) }},
idx_tup_read AS {{ conn|qtIdent(_('Index tuples read')) }},
idx_tup_fetch AS {{ conn|qtIdent(_('Index tuples fetched')) }},
idx_blks_read AS {{ conn|qtIdent(_('Index blocks read')) }},
idx_blks_hit AS {{ conn|qtIdent(_('Index blocks hit')) }},
pg_size_pretty(pg_relation_size({{ idx }}::OID)) AS {{ conn|qtIdent(_('Index size')) }}
{#=== Extended stats ===#}
{% if is_pgstattuple %}
,version AS {{ conn|qtIdent(_('Version')) }},
tree_level AS {{ conn|qtIdent(_('Tree level')) }},
pg_size_pretty(index_size) AS {{ conn|qtIdent(_('Index size')) }},
root_block_no AS {{ conn|qtIdent(_('Root block no')) }},
internal_pages AS {{ conn|qtIdent(_('Internal pages')) }},
leaf_pages AS {{ conn|qtIdent(_('Leaf pages')) }},
empty_pages AS {{ conn|qtIdent(_('Empty pages')) }},
deleted_pages AS {{ conn|qtIdent(_('Deleted pages')) }},
avg_leaf_density AS {{ conn|qtIdent(_('Average leaf density')) }},
leaf_fragmentation AS {{ conn|qtIdent(_('Leaf fragmentation')) }}
FROM
pgstatindex('{{conn|qtIdent(schema)}}.{{conn|qtIdent(index)}}'), pg_stat_all_indexes stat
{% else %}
FROM
pg_stat_all_indexes stat
{% endif %}
JOIN pg_statio_all_indexes statio ON stat.indexrelid = statio.indexrelid
JOIN pg_class cl ON cl.oid=stat.indexrelid
WHERE stat.indexrelid = {{ idx }}::OID

View File

@ -0,0 +1,28 @@
SELECT
idx_scan AS {{ conn|qtIdent(_('Index scans')) }},
idx_tup_read AS {{ conn|qtIdent(_('Index tuples read')) }},
idx_tup_fetch AS {{ conn|qtIdent(_('Index tuples fetched')) }},
idx_blks_read AS {{ conn|qtIdent(_('Index blocks read')) }},
idx_blks_hit AS {{ conn|qtIdent(_('Index blocks hit')) }},
pg_size_pretty(pg_relation_size({{ cid }}::OID)) AS {{ conn|qtIdent(_('Index size')) }}
{#=== Extended stats ===#}
{% if is_pgstattuple %}
,version AS {{ conn|qtIdent(_('Version')) }},
tree_level AS {{ conn|qtIdent(_('Tree level')) }},
pg_size_pretty(index_size) AS {{ conn|qtIdent(_('Index size')) }},
root_block_no AS {{ conn|qtIdent(_('Root block no')) }},
internal_pages AS {{ conn|qtIdent(_('Internal pages')) }},
leaf_pages AS {{ conn|qtIdent(_('Leaf pages')) }},
empty_pages AS {{ conn|qtIdent(_('Empty pages')) }},
deleted_pages AS {{ conn|qtIdent(_('Deleted pages')) }},
avg_leaf_density AS {{ conn|qtIdent(_('Average leaf density')) }},
leaf_fragmentation AS {{ conn|qtIdent(_('Leaf fragmentation')) }}
FROM
pgstatindex('{{conn|qtIdent(schema)}}.{{conn|qtIdent(name)}}'), pg_stat_all_indexes stat
{% else %}
FROM
pg_stat_all_indexes stat
{% endif %}
JOIN pg_statio_all_indexes statio ON stat.indexrelid = statio.indexrelid
JOIN pg_class cl ON cl.oid=stat.indexrelid
WHERE stat.indexrelid = {{ cid }}::OID

View File

@ -12,7 +12,8 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
node: 'table',
label: '{{ _('Tables') }}',
type: 'coll-table',
columns: ['name', 'relowner', 'description']
columns: ['name', 'relowner', 'description'],
hasStatistics: true
});
};
@ -23,6 +24,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
collection_type: 'coll-table',
hasSQL: true,
hasDepends: true,
hasStatistics: true,
sqlAlterHelp: 'sql-altertable.html',
sqlCreateHelp: 'sql-createtable.html',
dialogHelp: '{{ url_for('help.static', filename='table_dialog.html') }}',

View File

@ -0,0 +1,29 @@
SELECT
st.relname AS {{ conn|qtIdent(_('Table name')) }},
n_tup_ins AS {{ conn|qtIdent(_('Tuples inserted')) }},
n_tup_upd AS {{ conn|qtIdent(_('Tuples updated')) }},
n_tup_del AS {{ conn|qtIdent(_('Tuples deleted')) }},
n_tup_hot_upd AS {{ conn|qtIdent(_('Tuples HOT updated')) }},
n_live_tup AS {{ conn|qtIdent(_('Live tuples')) }},
n_dead_tup AS {{ conn|qtIdent(_('Dead tuples')) }},
last_vacuum AS {{ conn|qtIdent(_('Last vacuum')) }},
last_autovacuum AS {{ conn|qtIdent(_('Last autovacuum')) }},
last_analyze AS {{ conn|qtIdent(_('Last analyze')) }},
last_autoanalyze AS {{ conn|qtIdent(_('Last autoanalyze')) }},
vacuum_count AS {{ conn|qtIdent(_('Vacuum counter')) }},
autovacuum_count AS {{ conn|qtIdent(_('Autovacuum counter')) }},
analyze_count AS {{ conn|qtIdent(_('Analyze counter')) }},
autoanalyze_count AS {{ conn|qtIdent(_('Autoanalyze counter')) }},
pg_size_pretty(pg_relation_size(st.relid)
+ CASE WHEN cl.reltoastrelid = 0 THEN 0 ELSE pg_relation_size(cl.reltoastrelid)
+ COALESCE((SELECT SUM(pg_relation_size(indexrelid))
FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0) END
+ COALESCE((SELECT SUM(pg_relation_size(indexrelid))
FROM pg_index WHERE indrelid=st.relid)::int8, 0)) AS {{ conn|qtIdent(_('Size')) }}
FROM
pg_stat_all_tables st
JOIN
pg_class cl on cl.oid=st.relid
WHERE
schemaname = {{schema_name|qtLiteral}}
ORDER BY st.relname;

View File

@ -0,0 +1 @@
SELECT nsp.nspname FROM pg_namespace nsp WHERE nsp.oid = {{ scid|qtLiteral }};

View File

@ -0,0 +1,8 @@
SELECT
rel.relname AS name
FROM
pg_class rel
WHERE
rel.relkind IN ('r','s','t')
AND rel.relnamespace = {{ scid }}::oid
AND rel.oid = {{ tid }}::oid;

View File

@ -0,0 +1,57 @@
SELECT
seq_scan AS {{ conn|qtIdent(_('Sequential scans')) }},
seq_tup_read AS {{ conn|qtIdent(_('Sequential tuples read')) }},
idx_scan AS {{ conn|qtIdent(_('Index scans')) }},
idx_tup_fetch AS {{ conn|qtIdent(_('Index tuples fetched')) }},
n_tup_ins AS {{ conn|qtIdent(_('Tuples inserted')) }},
n_tup_upd AS {{ conn|qtIdent(_('Tuples updated')) }},
n_tup_del AS {{ conn|qtIdent(_('Tuples deleted')) }},
n_tup_hot_upd AS {{ conn|qtIdent(_('Tuples HOT updated')) }},
n_live_tup AS {{ conn|qtIdent(_('Live tuples')) }},
n_dead_tup AS {{ conn|qtIdent(_('Dead tuples')) }},
heap_blks_read AS {{ conn|qtIdent(_('Heap blocks read')) }},
heap_blks_hit AS {{ conn|qtIdent(_('Heap blocks hit')) }},
idx_blks_read AS {{ conn|qtIdent(_('Index blocks read')) }},
idx_blks_hit AS {{ conn|qtIdent(_('Index blocks hit')) }},
toast_blks_read AS {{ conn|qtIdent(_('Toast blocks read')) }},
toast_blks_hit AS {{ conn|qtIdent(_('Toast blocks hit')) }},
tidx_blks_read AS {{ conn|qtIdent(_('Toast index blocks read')) }},
tidx_blks_hit AS {{ conn|qtIdent(_('Toast index blocks hit')) }},
last_vacuum AS {{ conn|qtIdent(_('Last vacuum')) }},
last_autovacuum AS {{ conn|qtIdent(_('Last autovacuum')) }},
last_analyze AS {{ conn|qtIdent(_('Last analyze')) }},
last_autoanalyze AS {{ conn|qtIdent(_('Last autoanalyze')) }},
vacuum_count AS {{ conn|qtIdent(_('Vacuum counter')) }},
autovacuum_count AS {{ conn|qtIdent(_('Autovacuum counter')) }},
analyze_count AS {{ conn|qtIdent(_('Analyze counter')) }},
autoanalyze_count AS {{ conn|qtIdent(_('Autoanalyze counter')) }},
pg_size_pretty(pg_relation_size(stat.relid)) AS {{ conn|qtIdent(_('Table size')) }},
CASE WHEN cl.reltoastrelid = 0 THEN NULL ELSE pg_size_pretty(pg_relation_size(cl.reltoastrelid)
+ COALESCE((SELECT SUM(pg_relation_size(indexrelid))
FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0))
END AS {{ conn|qtIdent(_('Toast table size')) }},
pg_size_pretty(COALESCE((SELECT SUM(pg_relation_size(indexrelid))
FROM pg_index WHERE indrelid=stat.relid)::int8, 0))
AS {{ conn|qtIdent(_('Indexes size')) }}
{% if is_pgstattuple %}
{#== EXTENDED STATS ==#}
,tuple_count AS {{ conn|qtIdent(_('Tuple count')) }},
pg_size_pretty(tuple_len) AS {{ conn|qtIdent(_('Tuple length')) }},
tuple_percent AS {{ conn|qtIdent(_('Tuple percent')) }},
dead_tuple_count AS {{ conn|qtIdent(_('Dead tuple count')) }},
pg_size_pretty(dead_tuple_len) AS {{ conn|qtIdent(_('Dead tuple length')) }},
dead_tuple_percent AS {{ conn|qtIdent(_('Dead tuple percent')) }},
pg_size_pretty(free_space) AS {{ conn|qtIdent(_('Free space')) }},
free_percent AS {{ conn|qtIdent(_('Free percent')) }}
FROM
pgstattuple('{{schema_name}}.{{table_name}}'), pg_stat_all_tables stat
{% else %}
FROM
pg_stat_all_tables stat
{% endif %}
JOIN
pg_statio_all_tables statio ON stat.relid = statio.relid
JOIN
pg_class cl ON cl.oid=stat.relid
WHERE
stat.relid = {{ tid }}::oid

View File

@ -0,0 +1,29 @@
SELECT
st.relname AS {{ conn|qtIdent(_('Table name')) }},
n_tup_ins AS {{ conn|qtIdent(_('Tuples inserted')) }},
n_tup_upd AS {{ conn|qtIdent(_('Tuples updated')) }},
n_tup_del AS {{ conn|qtIdent(_('Tuples deleted')) }},
n_tup_hot_upd AS {{ conn|qtIdent(_('Tuples HOT updated')) }},
n_live_tup AS {{ conn|qtIdent(_('Live tuples')) }},
n_dead_tup AS {{ conn|qtIdent(_('Dead tuples')) }},
last_vacuum AS {{ conn|qtIdent(_('Last vacuum')) }},
last_autovacuum AS {{ conn|qtIdent(_('Last autovacuum')) }},
last_analyze AS {{ conn|qtIdent(_('Last analyze')) }},
last_autoanalyze AS {{ conn|qtIdent(_('Last autoanalyze')) }},
vacuum_count AS {{ conn|qtIdent(_('Vacuum counter')) }},
autovacuum_count AS {{ conn|qtIdent(_('Autovacuum counter')) }},
analyze_count AS {{ conn|qtIdent(_('Analyze counter')) }},
autoanalyze_count AS {{ conn|qtIdent(_('Autoanalyze counter')) }},
pg_size_pretty(pg_relation_size(st.relid)
+ CASE WHEN cl.reltoastrelid = 0 THEN 0 ELSE pg_relation_size(cl.reltoastrelid)
+ COALESCE((SELECT SUM(pg_relation_size(indexrelid))
FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0) END
+ COALESCE((SELECT SUM(pg_relation_size(indexrelid))
FROM pg_index WHERE indrelid=st.relid)::int8, 0)) AS {{ conn|qtIdent(_('Size')) }}
FROM
pg_stat_all_tables st
JOIN
pg_class cl on cl.oid=st.relid
WHERE
schemaname = {{schema_name|qtLiteral}}
ORDER BY st.relname;

View File

@ -0,0 +1 @@
SELECT nsp.nspname FROM pg_namespace nsp WHERE nsp.oid = {{ scid|qtLiteral }};

View File

@ -0,0 +1,8 @@
SELECT
rel.relname AS name
FROM
pg_class rel
WHERE
rel.relkind IN ('r','s','t')
AND rel.relnamespace = {{ scid }}::oid
AND rel.oid = {{ tid }}::oid;

View File

@ -0,0 +1,57 @@
SELECT
seq_scan AS {{ conn|qtIdent(_('Sequential scans')) }},
seq_tup_read AS {{ conn|qtIdent(_('Sequential tuples read')) }},
idx_scan AS {{ conn|qtIdent(_('Index scans')) }},
idx_tup_fetch AS {{ conn|qtIdent(_('Index tuples fetched')) }},
n_tup_ins AS {{ conn|qtIdent(_('Tuples inserted')) }},
n_tup_upd AS {{ conn|qtIdent(_('Tuples updated')) }},
n_tup_del AS {{ conn|qtIdent(_('Tuples deleted')) }},
n_tup_hot_upd AS {{ conn|qtIdent(_('Tuples HOT updated')) }},
n_live_tup AS {{ conn|qtIdent(_('Live tuples')) }},
n_dead_tup AS {{ conn|qtIdent(_('Dead tuples')) }},
heap_blks_read AS {{ conn|qtIdent(_('Heap blocks read')) }},
heap_blks_hit AS {{ conn|qtIdent(_('Heap blocks hit')) }},
idx_blks_read AS {{ conn|qtIdent(_('Index blocks read')) }},
idx_blks_hit AS {{ conn|qtIdent(_('Index blocks hit')) }},
toast_blks_read AS {{ conn|qtIdent(_('Toast blocks read')) }},
toast_blks_hit AS {{ conn|qtIdent(_('Toast blocks hit')) }},
tidx_blks_read AS {{ conn|qtIdent(_('Toast index blocks read')) }},
tidx_blks_hit AS {{ conn|qtIdent(_('Toast index blocks hit')) }},
last_vacuum AS {{ conn|qtIdent(_('Last vacuum')) }},
last_autovacuum AS {{ conn|qtIdent(_('Last autovacuum')) }},
last_analyze AS {{ conn|qtIdent(_('Last analyze')) }},
last_autoanalyze AS {{ conn|qtIdent(_('Last autoanalyze')) }},
vacuum_count AS {{ conn|qtIdent(_('Vacuum counter')) }},
autovacuum_count AS {{ conn|qtIdent(_('Autovacuum counter')) }},
analyze_count AS {{ conn|qtIdent(_('Analyze counter')) }},
autoanalyze_count AS {{ conn|qtIdent(_('Autoanalyze counter')) }},
pg_size_pretty(pg_relation_size(stat.relid)) AS {{ conn|qtIdent(_('Table size')) }},
CASE WHEN cl.reltoastrelid = 0 THEN NULL ELSE pg_size_pretty(pg_relation_size(cl.reltoastrelid)
+ COALESCE((SELECT SUM(pg_relation_size(indexrelid))
FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0))
END AS {{ conn|qtIdent(_('Toast table size')) }},
pg_size_pretty(COALESCE((SELECT SUM(pg_relation_size(indexrelid))
FROM pg_index WHERE indrelid=stat.relid)::int8, 0))
AS {{ conn|qtIdent(_('Indexes size')) }}
{% if is_pgstattuple %}
{#== EXTENDED STATS ==#}
,tuple_count AS {{ conn|qtIdent(_('Tuple count')) }},
pg_size_pretty(tuple_len) AS {{ conn|qtIdent(_('Tuple length')) }},
tuple_percent AS {{ conn|qtIdent(_('Tuple percent')) }},
dead_tuple_count AS {{ conn|qtIdent(_('Dead tuple count')) }},
pg_size_pretty(dead_tuple_len) AS {{ conn|qtIdent(_('Dead tuple length')) }},
dead_tuple_percent AS {{ conn|qtIdent(_('Dead tuple percent')) }},
pg_size_pretty(free_space) AS {{ conn|qtIdent(_('Free space')) }},
free_percent AS {{ conn|qtIdent(_('Free percent')) }}
FROM
pgstattuple('{{schema_name}}.{{table_name}}'), pg_stat_all_tables stat
{% else %}
FROM
pg_stat_all_tables stat
{% endif %}
JOIN
pg_statio_all_tables statio ON stat.relid = statio.relid
JOIN
pg_class cl ON cl.oid=stat.relid
WHERE
stat.relid = {{ tid }}::oid

View File

@ -1,15 +1,15 @@
SELECT
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
numbackends AS {{ conn|qtIdent(_('Backends')) }},
xact_commit AS {{ conn|qtIdent(_('Xact Committed')) }},
xact_rollback AS {{ conn|qtIdent(_('Xact Rolled back')) }},
blks_read AS {{ conn|qtIdent(_('Blocks Read')) }},
blks_hit AS {{ conn|qtIdent(_('Blocks Hit')) }},
tup_returned AS {{ conn|qtIdent(_('Tuples Returned')) }},
tup_fetched AS {{ conn|qtIdent(_('Tuples Fetched')) }},
tup_inserted AS {{ conn|qtIdent(_('Tuples Inserted')) }},
tup_updated AS {{ conn|qtIdent(_('Tuples Updated')) }},
tup_deleted AS {{ conn|qtIdent(_('Tuples Deleted')) }},
xact_commit AS {{ conn|qtIdent(_('Xact committed')) }},
xact_rollback AS {{ conn|qtIdent(_('Xact rolled back')) }},
blks_read AS {{ conn|qtIdent(_('Blocks read')) }},
blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }},
tup_returned AS {{ conn|qtIdent(_('Tuples returned')) }},
tup_fetched AS {{ conn|qtIdent(_('Tuples fetched')) }},
tup_inserted AS {{ conn|qtIdent(_('Tuples inserted')) }},
tup_updated AS {{ conn|qtIdent(_('Tuples updated')) }},
tup_deleted AS {{ conn|qtIdent(_('Tuples deleted')) }},
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},

View File

@ -1,15 +1,15 @@
SELECT
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
numbackends AS {{ conn|qtIdent(_('Backends')) }},
xact_commit AS {{ conn|qtIdent(_('Xact Committed')) }},
xact_rollback AS {{ conn|qtIdent(_('Xact Rolled back')) }},
blks_read AS {{ conn|qtIdent(_('Blocks Read')) }},
blks_hit AS {{ conn|qtIdent(_('Blocks Hit')) }},
tup_returned AS {{ conn|qtIdent(_('Tuples Returned')) }},
tup_fetched AS {{ conn|qtIdent(_('Tuples Fetched')) }},
tup_inserted AS {{ conn|qtIdent(_('Tuples Inserted')) }},
tup_updated AS {{ conn|qtIdent(_('Tuples Updated')) }},
tup_deleted AS {{ conn|qtIdent(_('Tuples Deleted')) }},
xact_commit AS {{ conn|qtIdent(_('Xact committed')) }},
xact_rollback AS {{ conn|qtIdent(_('Xact rolled back')) }},
blks_read AS {{ conn|qtIdent(_('Blocks read')) }},
blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }},
tup_returned AS {{ conn|qtIdent(_('Tuples returned')) }},
tup_fetched AS {{ conn|qtIdent(_('Tuples fetched')) }},
tup_inserted AS {{ conn|qtIdent(_('Tuples inserted')) }},
tup_updated AS {{ conn|qtIdent(_('Tuples updated')) }},
tup_deleted AS {{ conn|qtIdent(_('Tuples deleted')) }},
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},

View File

@ -1,15 +1,15 @@
SELECT
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
numbackends AS {{ conn|qtIdent(_('Backends')) }},
xact_commit AS {{ conn|qtIdent(_('Xact Committed')) }},
xact_rollback AS {{ conn|qtIdent(_('Xact Rolled back')) }},
blks_read AS {{ conn|qtIdent(_('Blocks Read')) }},
blks_hit AS {{ conn|qtIdent(_('Blocks Hit')) }},
tup_returned AS {{ conn|qtIdent(_('Tuples Returned')) }},
tup_fetched AS {{ conn|qtIdent(_('Tuples Fetched')) }},
tup_inserted AS {{ conn|qtIdent(_('Tuples Inserted')) }},
tup_updated AS {{ conn|qtIdent(_('Tuples Updated')) }},
tup_deleted AS {{ conn|qtIdent(_('Tuples Deleted')) }},
xact_commit AS {{ conn|qtIdent(_('Xact committed')) }},
xact_rollback AS {{ conn|qtIdent(_('Xact rolled back')) }},
blks_read AS {{ conn|qtIdent(_('Blocks read')) }},
blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }},
tup_returned AS {{ conn|qtIdent(_('Tuples returned')) }},
tup_fetched AS {{ conn|qtIdent(_('Tuples fetched')) }},
tup_inserted AS {{ conn|qtIdent(_('Tuples inserted')) }},
tup_updated AS {{ conn|qtIdent(_('Tuples updated')) }},
tup_deleted AS {{ conn|qtIdent(_('Tuples deleted')) }},
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},