mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Statistics support remaining object types that support them.
This commit is contained in:
parent
ac2612264c
commit
4ace8bb5b6
@ -1295,6 +1295,35 @@ It may have been removed by another user or moved to another schema.
|
|||||||
|
|
||||||
return ajax_response(response=sql)
|
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)
|
FunctionView.register_node_view(blueprint)
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
|||||||
collection_type: 'coll-function',
|
collection_type: 'coll-function',
|
||||||
hasSQL: true,
|
hasSQL: true,
|
||||||
hasDepends: true,
|
hasDepends: true,
|
||||||
|
hasStatistics: true,
|
||||||
hasScriptTypes: ['create', 'select'],
|
hasScriptTypes: ['create', 'select'],
|
||||||
parent_type: ['schema', 'catalog'],
|
parent_type: ['schema', 'catalog'],
|
||||||
Init: function(args) {
|
Init: function(args) {
|
||||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -29,6 +29,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify, Function) {
|
|||||||
collection_type: 'coll-procedure',
|
collection_type: 'coll-procedure',
|
||||||
hasSQL: true,
|
hasSQL: true,
|
||||||
hasDepends: true,
|
hasDepends: true,
|
||||||
|
hasStatistics: true,
|
||||||
hasScriptTypes: ['create', 'exec'],
|
hasScriptTypes: ['create', 'exec'],
|
||||||
parent_type: ['schema', 'catalog'],
|
parent_type: ['schema', 'catalog'],
|
||||||
Init: function() {
|
Init: function() {
|
||||||
|
@ -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
|
@ -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
|
@ -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
|
@ -25,6 +25,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
|||||||
collection_type: 'coll-trigger_function',
|
collection_type: 'coll-trigger_function',
|
||||||
hasSQL: true,
|
hasSQL: true,
|
||||||
hasDepends: true,
|
hasDepends: true,
|
||||||
|
hasStatistics: true,
|
||||||
parent_type: ['schema', 'catalog'],
|
parent_type: ['schema', 'catalog'],
|
||||||
Init: function(args) {
|
Init: function(args) {
|
||||||
/* Avoid mulitple registration of menus */
|
/* Avoid mulitple registration of menus */
|
||||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -688,5 +688,33 @@ class SequenceView(PGChildNodeView):
|
|||||||
status=200
|
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)
|
SequenceView.register_node_view(blueprint)
|
||||||
|
@ -24,6 +24,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
|||||||
collection_type: 'coll-sequence',
|
collection_type: 'coll-sequence',
|
||||||
hasSQL: true,
|
hasSQL: true,
|
||||||
hasDepends: true,
|
hasDepends: true,
|
||||||
|
hasStatistics: true,
|
||||||
parent_type: ['schema', 'catalog'],
|
parent_type: ['schema', 'catalog'],
|
||||||
Init: function() {
|
Init: function() {
|
||||||
/* Avoid mulitple registration of menus */
|
/* Avoid mulitple registration of menus */
|
||||||
|
@ -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
|
@ -233,7 +233,7 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
|
|||||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||||
'sql': [{'get': 'sql'}],
|
'sql': [{'get': 'sql'}],
|
||||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||||
'stats': [{'get': 'statistics'}],
|
'stats': [{'get': 'statistics'}, {'get': 'statistics'}],
|
||||||
'dependency': [{'get': 'dependencies'}],
|
'dependency': [{'get': 'dependencies'}],
|
||||||
'dependent': [{'get': 'dependents'}],
|
'dependent': [{'get': 'dependents'}],
|
||||||
'module.js': [{}, {}, {'get': 'module_js'}],
|
'module.js': [{}, {}, {'get': 'module_js'}],
|
||||||
@ -2806,5 +2806,78 @@ class TableView(PGChildNodeView, DataTypeReader, VacuumSettings):
|
|||||||
|
|
||||||
return ajax_response(response=sql)
|
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)
|
TableView.register_node_view(blueprint)
|
||||||
|
@ -902,5 +902,47 @@ class ColumnsView(PGChildNodeView, DataTypeReader):
|
|||||||
status=200
|
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)
|
ColumnsView.register_node_view(blueprint)
|
||||||
|
@ -81,6 +81,7 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
hasDepends: true,
|
hasDepends: true,
|
||||||
|
hasStatistics: true,
|
||||||
Init: function() {
|
Init: function() {
|
||||||
/* Avoid mulitple registration of menus */
|
/* Avoid mulitple registration of menus */
|
||||||
if (this.initialized)
|
if (this.initialized)
|
||||||
|
@ -814,6 +814,62 @@ class ExclusionConstraintView(PGChildNodeView):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return internal_server_error(errormsg=str(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(
|
constraint = ConstraintRegistry(
|
||||||
'exclusion_constraint', ExclusionConstraintModule, ExclusionConstraintView
|
'exclusion_constraint', ExclusionConstraintModule, ExclusionConstraintView
|
||||||
)
|
)
|
||||||
|
@ -608,6 +608,7 @@ function($, _, S, pgAdmin, pgBrowser, Alertify) {
|
|||||||
canDrop: true,
|
canDrop: true,
|
||||||
canDropCascade: true,
|
canDropCascade: true,
|
||||||
hasDepends: true,
|
hasDepends: true,
|
||||||
|
hasStatistics: true,
|
||||||
Init: function() {
|
Init: function() {
|
||||||
/* Avoid multiple registration of menus */
|
/* Avoid multiple registration of menus */
|
||||||
if (this.initialized)
|
if (this.initialized)
|
||||||
|
@ -845,6 +845,62 @@ class IndexConstraintView(PGChildNodeView):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return internal_server_error(errormsg=str(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):
|
class PrimaryKeyConstraintView(IndexConstraintView):
|
||||||
node_type = 'primary_key'
|
node_type = 'primary_key'
|
||||||
|
@ -18,6 +18,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
hasSQL: true,
|
hasSQL: true,
|
||||||
hasDepends: false,
|
hasDepends: false,
|
||||||
|
hasStatistics: true,
|
||||||
parent_type: 'table',
|
parent_type: 'table',
|
||||||
canDrop: true,
|
canDrop: true,
|
||||||
canDropCascade: true,
|
canDropCascade: true,
|
||||||
|
@ -200,7 +200,7 @@ class IndexesView(PGChildNodeView):
|
|||||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||||
'sql': [{'get': 'sql'}],
|
'sql': [{'get': 'sql'}],
|
||||||
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
'msql': [{'get': 'msql'}, {'get': 'msql'}],
|
||||||
'stats': [{'get': 'statistics'}],
|
'stats': [{'get': 'statistics'}, {'get': 'statistics'}],
|
||||||
'dependency': [{'get': 'dependencies'}],
|
'dependency': [{'get': 'dependencies'}],
|
||||||
'dependent': [{'get': 'dependents'}],
|
'dependent': [{'get': 'dependents'}],
|
||||||
'module.js': [{}, {}, {'get': 'module_js'}],
|
'module.js': [{}, {}, {'get': 'module_js'}],
|
||||||
@ -871,4 +871,74 @@ class IndexesView(PGChildNodeView):
|
|||||||
status=200
|
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)
|
IndexesView.register_node_view(blueprint)
|
||||||
|
@ -11,7 +11,8 @@ function($, _, S, pgAdmin, pgBrowser, Backform, alertify) {
|
|||||||
type: 'coll-index',
|
type: 'coll-index',
|
||||||
sqlAlterHelp: 'sql-alterindex.html',
|
sqlAlterHelp: 'sql-alterindex.html',
|
||||||
sqlCreateHelp: 'sql-createindex.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') }}',
|
label: '{{ _('Index') }}',
|
||||||
hasSQL: true,
|
hasSQL: true,
|
||||||
hasDepends: true,
|
hasDepends: true,
|
||||||
|
hasStatistics: true,
|
||||||
Init: function() {
|
Init: function() {
|
||||||
/* Avoid mulitple registration of menus */
|
/* Avoid mulitple registration of menus */
|
||||||
if (this.initialized)
|
if (this.initialized)
|
||||||
|
@ -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}};
|
@ -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}};
|
@ -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
|
@ -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
|
@ -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;
|
@ -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
|
@ -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
|
@ -12,7 +12,8 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
|
|||||||
node: 'table',
|
node: 'table',
|
||||||
label: '{{ _('Tables') }}',
|
label: '{{ _('Tables') }}',
|
||||||
type: 'coll-table',
|
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',
|
collection_type: 'coll-table',
|
||||||
hasSQL: true,
|
hasSQL: true,
|
||||||
hasDepends: true,
|
hasDepends: true,
|
||||||
|
hasStatistics: true,
|
||||||
sqlAlterHelp: 'sql-altertable.html',
|
sqlAlterHelp: 'sql-altertable.html',
|
||||||
sqlCreateHelp: 'sql-createtable.html',
|
sqlCreateHelp: 'sql-createtable.html',
|
||||||
dialogHelp: '{{ url_for('help.static', filename='table_dialog.html') }}',
|
dialogHelp: '{{ url_for('help.static', filename='table_dialog.html') }}',
|
||||||
|
@ -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;
|
@ -0,0 +1 @@
|
|||||||
|
SELECT nsp.nspname FROM pg_namespace nsp WHERE nsp.oid = {{ scid|qtLiteral }};
|
@ -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;
|
@ -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
|
@ -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;
|
@ -0,0 +1 @@
|
|||||||
|
SELECT nsp.nspname FROM pg_namespace nsp WHERE nsp.oid = {{ scid|qtLiteral }};
|
@ -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;
|
@ -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
|
@ -1,15 +1,15 @@
|
|||||||
SELECT
|
SELECT
|
||||||
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
|
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
|
||||||
numbackends AS {{ conn|qtIdent(_('Backends')) }},
|
numbackends AS {{ conn|qtIdent(_('Backends')) }},
|
||||||
xact_commit AS {{ conn|qtIdent(_('Xact Committed')) }},
|
xact_commit AS {{ conn|qtIdent(_('Xact committed')) }},
|
||||||
xact_rollback AS {{ conn|qtIdent(_('Xact Rolled back')) }},
|
xact_rollback AS {{ conn|qtIdent(_('Xact rolled back')) }},
|
||||||
blks_read AS {{ conn|qtIdent(_('Blocks Read')) }},
|
blks_read AS {{ conn|qtIdent(_('Blocks read')) }},
|
||||||
blks_hit AS {{ conn|qtIdent(_('Blocks Hit')) }},
|
blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }},
|
||||||
tup_returned AS {{ conn|qtIdent(_('Tuples Returned')) }},
|
tup_returned AS {{ conn|qtIdent(_('Tuples returned')) }},
|
||||||
tup_fetched AS {{ conn|qtIdent(_('Tuples Fetched')) }},
|
tup_fetched AS {{ conn|qtIdent(_('Tuples fetched')) }},
|
||||||
tup_inserted AS {{ conn|qtIdent(_('Tuples Inserted')) }},
|
tup_inserted AS {{ conn|qtIdent(_('Tuples inserted')) }},
|
||||||
tup_updated AS {{ conn|qtIdent(_('Tuples Updated')) }},
|
tup_updated AS {{ conn|qtIdent(_('Tuples updated')) }},
|
||||||
tup_deleted AS {{ conn|qtIdent(_('Tuples Deleted')) }},
|
tup_deleted AS {{ conn|qtIdent(_('Tuples deleted')) }},
|
||||||
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
|
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
|
||||||
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
|
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
|
||||||
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},
|
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
SELECT
|
SELECT
|
||||||
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
|
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
|
||||||
numbackends AS {{ conn|qtIdent(_('Backends')) }},
|
numbackends AS {{ conn|qtIdent(_('Backends')) }},
|
||||||
xact_commit AS {{ conn|qtIdent(_('Xact Committed')) }},
|
xact_commit AS {{ conn|qtIdent(_('Xact committed')) }},
|
||||||
xact_rollback AS {{ conn|qtIdent(_('Xact Rolled back')) }},
|
xact_rollback AS {{ conn|qtIdent(_('Xact rolled back')) }},
|
||||||
blks_read AS {{ conn|qtIdent(_('Blocks Read')) }},
|
blks_read AS {{ conn|qtIdent(_('Blocks read')) }},
|
||||||
blks_hit AS {{ conn|qtIdent(_('Blocks Hit')) }},
|
blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }},
|
||||||
tup_returned AS {{ conn|qtIdent(_('Tuples Returned')) }},
|
tup_returned AS {{ conn|qtIdent(_('Tuples returned')) }},
|
||||||
tup_fetched AS {{ conn|qtIdent(_('Tuples Fetched')) }},
|
tup_fetched AS {{ conn|qtIdent(_('Tuples fetched')) }},
|
||||||
tup_inserted AS {{ conn|qtIdent(_('Tuples Inserted')) }},
|
tup_inserted AS {{ conn|qtIdent(_('Tuples inserted')) }},
|
||||||
tup_updated AS {{ conn|qtIdent(_('Tuples Updated')) }},
|
tup_updated AS {{ conn|qtIdent(_('Tuples updated')) }},
|
||||||
tup_deleted AS {{ conn|qtIdent(_('Tuples Deleted')) }},
|
tup_deleted AS {{ conn|qtIdent(_('Tuples deleted')) }},
|
||||||
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
|
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
|
||||||
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
|
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
|
||||||
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},
|
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
SELECT
|
SELECT
|
||||||
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
|
{% if not did %}db.datname AS {{ conn|qtIdent(_('Database')) }}, {% endif %}
|
||||||
numbackends AS {{ conn|qtIdent(_('Backends')) }},
|
numbackends AS {{ conn|qtIdent(_('Backends')) }},
|
||||||
xact_commit AS {{ conn|qtIdent(_('Xact Committed')) }},
|
xact_commit AS {{ conn|qtIdent(_('Xact committed')) }},
|
||||||
xact_rollback AS {{ conn|qtIdent(_('Xact Rolled back')) }},
|
xact_rollback AS {{ conn|qtIdent(_('Xact rolled back')) }},
|
||||||
blks_read AS {{ conn|qtIdent(_('Blocks Read')) }},
|
blks_read AS {{ conn|qtIdent(_('Blocks read')) }},
|
||||||
blks_hit AS {{ conn|qtIdent(_('Blocks Hit')) }},
|
blks_hit AS {{ conn|qtIdent(_('Blocks hit')) }},
|
||||||
tup_returned AS {{ conn|qtIdent(_('Tuples Returned')) }},
|
tup_returned AS {{ conn|qtIdent(_('Tuples returned')) }},
|
||||||
tup_fetched AS {{ conn|qtIdent(_('Tuples Fetched')) }},
|
tup_fetched AS {{ conn|qtIdent(_('Tuples fetched')) }},
|
||||||
tup_inserted AS {{ conn|qtIdent(_('Tuples Inserted')) }},
|
tup_inserted AS {{ conn|qtIdent(_('Tuples inserted')) }},
|
||||||
tup_updated AS {{ conn|qtIdent(_('Tuples Updated')) }},
|
tup_updated AS {{ conn|qtIdent(_('Tuples updated')) }},
|
||||||
tup_deleted AS {{ conn|qtIdent(_('Tuples Deleted')) }},
|
tup_deleted AS {{ conn|qtIdent(_('Tuples deleted')) }},
|
||||||
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
|
stats_reset AS {{ conn|qtIdent(_('Last statistics reset')) }},
|
||||||
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
|
slave.confl_tablespace AS {{ conn|qtIdent(_('Tablespace conflicts')) }},
|
||||||
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},
|
slave.confl_lock AS {{ conn|qtIdent(_('Lock conflicts')) }},
|
||||||
|
Loading…
Reference in New Issue
Block a user