Ananda Postgres Assignment
Ananda Postgres Assignment
the following query returns top 5 biggest tables in the ecomm database
--------------------------------------------------------------------------
SELECT relname AS "relation",pg_size_pretty (pg_total_relation_size (C .oid)) AS
"total_size"
FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C .relnamespace) WHERE nspname
NOT IN ( 'pg_catalog','information_schema')
AND C .relkind <> 'i' AND nspname !~ '^pg_toast' ORDER BY pg_total_relation_size (C
.oid) DESC LIMIT 5;
SELECT pg_database.datname,pg_size_pretty(pg_database_size(pg_database.datname)) AS
size FROM pg_database;
ecomm=> SELECT
pg_database.datname,pg_size_pretty(pg_database_size(pg_database.datname)) AS size
FROM pg_database;
datname | size
---------------+---------
cloudsqladmin | 8305 kB
template0 | 8033 kB
postgres | 8185 kB
template1 | 8177 kB
ecomm | 11 MB
(5 rows)
===================================================================================
================
ecomm=> \d pg_stat_activity
View "pg_catalog.pg_stat_activity"
Column | Type | Collation | Nullable | Default
------------------+--------------------------+-----------+----------+---------
datid | oid |
| |
datname | name | | |
pid | integer | | |
usesysid | oid | | |
usename | name | | |
application_name | text | | |
client_addr | inet | | |
client_hostname | text | | |
client_port | integer | | |
backend_start | timestamp with time zone | | |
xact_start | timestamp with time zone | | |
query_start | timestamp with time zone | | |
state_change | timestamp with time zone | | |
wait_event_type | text | | |
wait_event | text | | |
state | text | | |
backend_xid | xid | | |
backend_xmin | xid | | |
query | text | | |
backend_type | text | | |
find the activities associated with the database by querying the pg_stat_activity
view
-----------------------------------------------------------------------------
SELECT * FROM pg_stat_activity WHERE datname = 'ecomm';
ecomm=> SELECT * FROM pg_stat_activity WHERE datname = 'ecomm';
datid | datname | pid | usesysid | usename |
application_name | client_addr | client_hostname | client_port |
backend_start |
xact_start | query_start | state_change
| wait_event_type | wait_event | state | backend_xid | backend_xmin |
query | backend_type
-------+---------+--------+----------+-----------------------------
+--------------------------+--------------+-----------------+-------------
+-------------------------------+------
-------------------------+-------------------------------
+-------------------------------+-----------------+------------+--------
+-------------+--------------+---------------------
------------------------------------+----------------
16467 | ecomm | 524363 | 17952 | ecomm_api | PostgreSQL
JDBC Driver | | | |
|
| |
| | | | | |
<insufficient privil
ege> |
16467 | ecomm | 524361 | 17952 | ecomm_api | PostgreSQL
JDBC Driver | | | |
|
| |
| | | | | |
<insufficient privil
ege> |
16467 | ecomm | 524509 | 17952 | ecomm_api | PostgreSQL
JDBC Driver | | | |
|
| |
| | | | | |
<insufficient privil
ege> |
16467 | ecomm | 524510 | 17952 | ecomm_api | PostgreSQL
JDBC Driver | | | |
|
| |
| | | | | |
<insufficient privil
ege> |
16467 | ecomm | 524511 | 17952 | ecomm_api | PostgreSQL
JDBC Driver | | | |
|
| |
| | | | | |
<insufficient privil
ege> |
16467 | ecomm | 524825 | 17952 | ecomm_api | PostgreSQL
JDBC Driver | | | |
|
| |
| | | | | |
<insufficient privil
ege> |
16467 | ecomm | 525016 | 17952 | ecomm_api | PostgreSQL
JDBC Driver | | | |
|
| |
| | | | | |
<insufficient privil
ege>
===================================================================================
==============================
performance tunning
==============================
pg_stats_statements
---------------------
It simply tracks execution statistics of SQL statements and can be an easy way to
find poor performing queries.
SELECT *
FROM
pg_stat_statements
ORDER BY
total_time DESC;
WITH ttl AS (
SELECT sum(total_time) AS total_time, sum(blk_read_time + blk_write_time) AS
io_time,
sum(total_time - blk_read_time - blk_write_time) AS cpu_time,
sum(calls) AS ncalls, sum(rows) AS total_rows
FROM pg_stat_statements WHERE dbid IN (
SELECT oid FROM pg_database WHERE datname=current_database())
)
SELECT *,(pss.total_time-pss.blk_read_time-pss.blk_write_time)/ttl.cpu_time*100
cpu_pct
FROM pg_stat_statements pss, ttl
WHERE (pss.total_time-pss.blk_read_time-pss.blk_write_time)/ttl.cpu_time >= 0.05
ORDER BY pss.total_time-pss.blk_read_time-pss.blk_write_time DESC LIMIT 1;
missing index
---------------
SELECT
relname,
seq_scan - idx_scan AS too_much_seq,
CASE
WHEN
seq_scan - coalesce(idx_scan, 0) > 0
THEN
'Missing Index?'
ELSE
'OK'
END,
pg_relation_size(relname::regclass) AS rel_size, seq_scan, idx_scan
FROM
pg_stat_all_tables
WHERE
schemaname = 'public'
AND pg_relation_size(relname::regclass) > 80000
ORDER BY
too_much_seq DESC;
ecomm=> SELECT
ecomm-> relname,
ecomm-> seq_scan - idx_scan AS too_much_seq,
ecomm-> CASE
ecomm-> WHEN
ecomm-> seq_scan - coalesce(idx_scan, 0) > 0
ecomm-> THEN
ecomm-> 'Missing Index?'
ecomm-> ELSE
ecomm-> 'OK'
ecomm-> END,
ecomm-> pg_relation_size(relname::regclass) AS rel_size, seq_scan, idx_scan
ecomm-> FROM
ecomm-> pg_stat_all_tables
ecomm-> WHERE
ecomm-> schemaname = 'public'
ecomm-> AND pg_relation_size(relname::regclass) > 80000
ecomm-> ORDER BY
ecomm-> too_much_seq DESC;
relname | too_much_seq | case | rel_size | seq_scan | idx_scan
---------+--------------+------+----------+----------+----------
(0 rows)
unused index
------------------
SELECT
indexrelid::regclass as index,
relid::regclass as table,
'DROP INDEX ' || indexrelid::regclass || ';' as drop_statement
FROM
pg_stat_user_indexes
JOIN
pg_index USING (indexrelid)
WHERE
idx_scan = 0
AND indisunique is false;
ecomm=> SELECT
ecomm-> indexrelid::regclass as index,
ecomm-> relid::regclass as table,
ecomm-> 'DROP INDEX ' || indexrelid::regclass || ';' as drop_statement
ecomm-> FROM
ecomm-> pg_stat_user_indexes
ecomm-> JOIN
ecomm-> pg_index USING (indexrelid)
ecomm-> WHERE
ecomm-> idx_scan = 0
ecomm-> AND indisunique is false;
index | table | drop_statement
-------+-------+----------------
(0 rows)
ecomm=> EXPLAIN (analyze, buffers) SELECT r.relname, a.attname FROM pg_class r JOIN
pg_attribute a ON a.attrelid=r.oid
ecomm-> WHERE a.attnum>0 AND NOT attisdropped;
QUERY PLAN
-----------------------------------------------------------------------------------
------------------------------------
Hash Join (cost=28.67..167.34 rows=2884 width=128) (actual time=0.284..3.778
rows=2887 loops=1)
Hash Cond: (a.attrelid = r.oid)
Buffers: shared hit=96
-> Seq Scan on pg_attribute a (cost=0.00..131.05 rows=2884 width=68) (actual
time=0.007..2.596 rows=2887 loops=1)
Filter: ((NOT attisdropped) AND (attnum > 0))
Rows Removed by Filter: 1200
Buffers: shared hit=80
-> Hash (cost=21.63..21.63 rows=563 width=68) (actual time=0.268..0.269
rows=564 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 64kB
Buffers: shared hit=16
-> Seq Scan on pg_class r (cost=0.00..21.63 rows=563 width=68) (actual
time=0.005..0.149 rows=564 loops=1)
Buffers: shared hit=16
Planning Time: 0.574 ms
Execution Time: 4.014 ms
(14 rows)
SELECT
pid,
now() - pg_stat_activity.query_start AS duration,
state,
query
FROM pg_stat_activity
WHERE state ='active' AND query NOT ILIKE '%pg_stat_activity%' AND (now() -
pg_stat_activity.query_start) > interval '5 seconds'
ORDER BY duration desc;
ecomm=> SELECT
ecomm-> pid,
ecomm-> now() - pg_stat_activity.query_start AS duration,
ecomm-> state,
ecomm-> query
ecomm-> FROM pg_stat_activity
ecomm-> WHERE state ='active' AND query NOT ILIKE '%pg_stat_activity%' AND (now() -
pg_stat_activity.query_start) > interval '5 seconds'
ecomm-> ORDER BY duration desc;
pid | duration | state | query
-----+----------+-------+-------
(0 rows)
ecomm=> SELECT
ecomm-> table_schema, table_name
ecomm-> FROM
ecomm-> information_schema.tables
ecomm-> WHERE
ecomm-> table_schema <> 'information_schema'
ecomm-> AND table_name NOT LIKE 'pg_%'
ecomm-> ORDER BY
ecomm-> table_schema,
ecomm-> table_name;
table_schema | table_name
--------------+----------------------------
ecomm | AUDIT_DATA
ecomm | BILLING_ADDRESS
ecomm | CA_CATEGORY
ecomm | CA_CATEGORY_VAL
ecomm | CA_UPLOAD
ecomm | COMMON_ADDRESS_INFO
ecomm | COMMON_CONTACT_INFO
ecomm | CONTACT
ecomm | CONTACT_BASIC_ATTR
ecomm | CONTACT_BASIC_ATTR_VAL
ecomm | CONTACT_CA_DEFAULTS
ecomm | CONTACT_CA_RSTR
ecomm | CONTACT_COSTALLOC_ATTR
ecomm | CONTACT_COSTALLOC_ATTR_VAL
ecomm | CONTACT_FLAGS
ecomm | CONTACT_FLAGS_VAL
ecomm | CONTACT_ORD_PREF
ecomm | CONTACT_ORD_PREF_VAL
ecomm | CONTACT_PROFILE
ecomm | CONTACT_ROLE
ecomm | CONTACT_SHIP_PREF
ecomm | CONTACT_SHIP_PREF_VAL
ecomm | CUSTOMER
ecomm | CUSTOMER_FLAG
ecomm | CUSTOMER_FLAG_VAL
ecomm | CUSTOMER_PROFILE
ecomm | CUSTOMER_SEGMENT
ecomm | CUSTOMER_SEGMENT_VAL
ecomm | CUST_BASIC_PREF
ecomm | CUST_BASIC_PREF_VAL
ecomm | CUST_CONTACT_RELATION
ecomm | CUST_COSTALLOC_PREF
ecomm | CUST_COSTALLOC_PREF_VAL
ecomm | CUST_ORDAPPR_PREF
ecomm | CUST_ORDAPPR_PREF_VAL
ecomm | MSG_AUDIT
ecomm | ORDERS
ecomm | PO_ORDER_HISTORY
ecomm | PURCHASE_ORDERS
ecomm | SHIPPING_ADDRESS
ecomm | ULTIMATE_ADDRESS
hit ratio:
============
SELECT
sum(heap_blks_read) as reads,
sum(heap_blks_hit) as hits,
ROUND(
sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)),
4
) as hit_ratio
FROM
pg_statio_user_tables;
ecomm=> SELECT
ecomm-> sum(heap_blks_read) as reads,
ecomm-> sum(heap_blks_hit) as hits,
ecomm-> ROUND(
ecomm(> sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)),
ecomm(> 4
ecomm(> ) as hit_ratio
ecomm-> FROM
ecomm-> pg_statio_user_tables;
reads | hits | hit_ratio
-------+-------+-----------
38 | 67616 | 0.9994